文档章节

浅谈ElasticSearch的嵌套存储模型

九劫散仙
 九劫散仙
发布于 2017/02/28 11:45
字数 1028
阅读 74
收藏 0

image 最近一个半月都在搞SparkStreaming+Hbase+Redis+ES相关的实时流项目开发,其中重度使用了ElasticSearch作为一个核心业务的数据存储,所以这段时间更新文章较少,现在开发基本完事,接下来的会写几篇有关ElastiSearch的使用心得。

大多数时候我们使用es都是用来存储业务比较简单的数据,比如日志log类居多,就算有一些有主外键关联的数据,我们也会提前join好,然后放入es中存储。

的确,扁平化后的数据存入索引,无论是写入,更新,查询都比较简单。但是有一些业务却没法扁平化后存储。比如我们这次的业务数据。由于业务本身比较复杂,先看下数据实体模型。

image

总共是三层模型,可以看到User(用户)包含多个Quest(题目),每个题目又包含多个Kp(知识点),其中User,Quest,Kp都是一个实体类,可以包含多个属性,按照es的字段类型应该叫做object类型,先说说为什么不能扁平化处理在写入索引,因为一旦扁平化其实只有统计知识点相关的聚合才是正确的,若想统计题目和人的一些聚合指标有些是查不出来的,因为一旦扁平前2级数据会被冗余放大好多倍,导致计算指标会出现问题。常规的count+distinct可以出来,但是一些sum指标就不对了,会多算冗余数据的和,而且没法再减出去,如果想做可能需要多次查询才能搞定,理想情况下,一次查询就能搞定大部分查询或聚合 所以只有嵌套设计才能贴合真实的数据模型,换做关系型数据需要三张表,用mongodb也可以但是查询+聚合就没有es这么强大和高效

三层嵌套的好处就是贴合实际的数据实体模型,但是带来的弊端也非常明显,对深层嵌套数据的删除,修改比较麻烦,虽然也能做到,但是每一层的数据量越大,性能可能就越低,所以嵌套方案,适合存储和查询多级嵌套数据,且更新和删除操作少的业务情况,尽量没有修改和删除。

es的嵌套查询和聚合支持都比较完善,并且支持嵌套反转查询。嵌套数据的添加可以使用script脚本方式来完成,直接将java的bean给转换完为json提交即可。

下面来看下动态mapping+嵌套类型设置,一个模板如下:

{
  "order": 0,
  "template": "work*",
  "settings": {
    "index": {
      "number_of_replicas": "0",
      "number_of_shards": "3"
    }
  },
  "mappings": {
    "_default_": {
      "dynamic_templates": [
        {
          "nested_kps": {
            "mapping": {
              "type": "nested"
            },
            "path_match": "quests.kps"
          }
        },
        {
          "nested_quests": {
            "mapping": {
              "type": "nested"
            },
            "match": "quests"
          }
        },
        {
          "string_fields": {
            "mapping": {
              "index": "not_analyzed",
              "type": "string"
            },
            "match": "*",
            "match_mapping_type": "string"
          }
        },
        {
          "message": {
            "mapping": {
              "index": "analyzed",
              "type": "string"
            },
            "match": "message",
            "match_mapping_type": "string"
          }
        },
        {
          "date_fields": {
            "mapping": {
              "doc_values": true,
              "type": "date"
            },
            "match": "*",
            "match_mapping_type": "date"
          }
        },
        {
          "float_fields": {
            "mapping": {
              "doc_values": true,
              "type": "float"
            },
            "match": "*",
            "match_mapping_type": "float"
          }
        },
        {
          "double_fields": {
            "mapping": {
              "doc_values": true,
              "type": "double"
            },
            "match": "*",
            "match_mapping_type": "double"
          }
        },
        {
          "integer_fields": {
            "mapping": {
              "doc_values": true,
              "type": "integer"
            },
            "match": "*",
            "match_mapping_type": "integer"
          }
        },
        {
          "long_fields": {
            "mapping": {
              "doc_values": true,
              "type": "long"
            },
            "match": "*",
            "match_mapping_type": "long"
          }
        }
      ],
      "_all": {
        "enabled": false
      }
    }
  },
  "aliases": {}
}

嵌套类型的关键词是nested,如果一个类型是nested,就相当于是设置了Java里面的List是一个集合对象list,可以有多个同一种类型的实体类数据,每个数据里面还可以有自己的嵌套类型或其他类型,上面的动态mapping里面数据类型设置各个类型的定义,并且根据path设置了嵌套的动态mapping设置。这样以来就相当于设置了三层嵌套。

到此我们应该能理解嵌套模型的定义和使用场景了,下篇会给出如何插入数据和使用script追加数据。

有什么问题可以扫码关注微信公众号:我是攻城师(woshigcs),在后台留言咨询。 技术债不能欠,健康债更不能欠, 求道之路,与君同行。

输入图片说明

© 著作权归作者所有

共有 人打赏支持
九劫散仙
粉丝 266
博文 175
码字总数 189625
作品 0
海淀
私信 提问
Elastic 在年度用户大会 Elastic{ON} 2018 上发布众多新功能和技术预览

下载超过 2.25 亿次,Elastic 公开 X-Pack 源代码 旧金山 (Elastic{ON} 2018) – 2018 年 2 月 27 日 – Elastic,Elasticsearch 和 Elastic Stack背后的公司,今天宣布其产品累计下载次数达...

Medcl
03/01
0
0
基于弹性堆栈(ELK堆栈)的日志分析、存储及展示

ELK简介 “ELK”是三个开源项目的首字母缩写:Elasticsearch,Logstash和Kibana。Elasticsearch是一个搜索和分析引擎。Logstash是一个服务器端数据处理管道,它同时从多个源中提取数据,对其...

cchenyz
08/22
0
0
CentOS7.3下ELK日志分析系统集群搭建

Elasticsearch是个基于Lucene实现的开源、分布式、restful的全文本搜索引擎,此外他还是一个分布式实时文档存储,其中每个文档的每个filed均是可被索引的数据,且可被搜索,也是一个带实时分...

wujunqi1996
07/14
0
0
机器学习利用 Elasticsearch 进行更智能搜索

众所周知,机器学习正在引领许多行业的变革。对于曾疲于用人工调整搜索相关性来捕捉细微差别的搜索行业就更是如此。人工调整已经实现了其能达到的最好效果,成熟的搜索公司不满足于此,试图建...

oschina
2017/03/03
5K
5
centos 7( linux )下安装elasticsearch教程

目录 概述 环境准备 elaticsearch简介 安装elasticsearch 彩蛋 概述 很久没有写博客了,最近在做全文检索的项目,发现elasticsearch踩了不少坑,百度点进去又是坑,在此记录一下自己的踩坑历程。...

java_龙
10/15
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Java Sound Programmer Guide

Introductory Material Preface For Whom This Guide Is Intended What this Guide Describes For More Information Chapter: 1 Introduction to the Java Sound API Design Goals Who is th......

祖冲之
14分钟前
1
0
HTTP协议状态码304和200区别

当浏览器第一次加载资源的时候,返回一般为200,意思是成功获取资源,并会在浏览器的缓存中记录下max-age; 当第二次访问的时候:如果只是用浏览器打开,那么浏览器会去判断这个资源在缓存里...

晚风0623
14分钟前
2
0
阿里云物联网平台体验(树莓派+Python篇)

虽然对阿里云物联网平台比较熟悉了,从一开始就有幸参与了飞凤平台(Link Develop 一站式开发平台的前身)的一些偏硬件接入的工作。但是同时也见证了阿里云物联网团队从几十人到数百人的迅速...

阿里云云栖社区
27分钟前
0
0
java单例设计模式

实现方法一 package com.hs.pattern.singleton;/** * 优点:实现简单 * 缺点:线程不安全 * 例如:当两个线程都运行到if( singleton == null ),而singleton确实为空,则两个线程都...

yangyangyyyy
32分钟前
1
0
MacOS下安装MongoDB数据库

官方链接:Install MongoDB Community Edition on macOS 推荐大家使用Homebrew安装 ##1.更新 Homebrew’s 包版本 brew update 2.安装MongoDB brew install mongodb 休息片刻,等他安装完就...

凌宇之蓝
32分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部