Elasticsearch数据建模

数据建模

  • 数据建模是创建数据模型的过程

  • 数据模型是对真实世界进行抽象描述的一种工具和方法,实现对现实世界的映射

    • 三个过程:概念模型=》逻辑模型=》数据模型

      • 数据模型:结合具体的数据库,在满足业务读写性能等需求的前提下,确定最终定义
  • 数据建模:功能需求+性能需求

    • 逻辑模型(功能需求)

      • 实体属性

        实体之间的关系

        搜索相关的配置

    • 物理模型(性能需求)

      • 索引模版
        • 分片数量
        • 索引Mapping
        • 字段配置
        • 关系处理
  • 对字段进行建模

  • 字段类型:

    • Text vs Keyword

      • Text

        • 用于全文本字段,文本会被Analyzer分词
        • 默认不支持聚合分析及排序。需要设置fielddata为true
      • Keyword

        • 用于id,枚举及不需要分词的文本。例如电话号码,email地址,手机号码,邮政编码,性别等
        • 适用于Filter(精确匹配),Sorting和Aggregations
      • 设置多字段类型

        默认会为文本类型设置成text,并且设置一个keyword的子字段

        在处理人类语言时,通过增加“英文”,“拼音”和“标准”分词器,提高搜索结果

        结构化数据

    • 结构化数据

      • 数值类型

      • 尽量选择贴近的类型。例如可以用byte,就不要用long

      • 枚举类型

      • 设置为keyword。即便是数字,也应该设置成keyword,获取更加好的性能

      • 其他

      • 日期/布尔/地理信息

    • 检索

      • 如不需要检索

        • Enable设置成false
      • 如不需要检索

        • Index设置成false
      • 对需要检索的字段,可以通过如下配置,设定存储粒度

        • Index_options/Norms:不需要归一化数据时,可以关闭
    • 聚合及排序

      • 如不需要排序和聚合分析

        • Enable设置成false
      • 如不需要排序或者聚合分析

        • Doc_value/fielddata设置成false
      • 更新频繁,聚合查询频繁的keyword类型的字段

        • 推荐eager_global_ordinals设置为true
    • 额外的存储

      • 是否需要专门存储当前字段数据

      • Disable _source:节约磁盘;适用于指标型数据

        • 一般建议考虑增加压缩比
        • 无法看到_source字段,无法ReIndex 无法Upadte
        • Kibana中无法做discovery
  • 最佳实践

  • 建模建议一:如何处理关联关系

  • 建模建议二:避免过多字段

    • 一个文档中,最好避免大量的字段
      • 过多的字段数不容易维护

        • Mapping信息保存在Cluster State中,数据量过大,对集群性能会有影响(Cluster State信息需要和所有的节点同步)
        • 删除或者修改数据需要reindex
      • 默认最大字段数是1000,可以设置index.mapping.tatal_fields.limt限定最大字段数

      • Dynamic vs Strict

        • Dynamic(生产环境中,尽量不用打开Dynamic)
          • true-未知字段会被自动加入
          • false-新字段不会被索引。但是会保存在_source
          • strict-新字段不会被索引,文档写入失败
        • Strict
          • 可以控制道字段级别

          

      • 当Dynamic设置为True,同时采用扁平化的设计且键值对过多会导致字段数量的膨胀,通过Nested对象保存key/value可以减少字段数量。

  • 建模建议三:避免正则查询

    • 通过 Inner Object避免低性能的正则匹配

 

1
2
3
4
5
6
7
8
{
"version":{
"display_name":"7.1.0",
"marjor":7,
"minor":1,
"hot_fix":0
}
}
  • 建模建议四:避免空值引起的聚合不准确
    • 使用Null_Value解决空值的问题

    • 建模建议五:为索引的Mapping加入Meta信息便于管理

1
2
3
4
5
6
7
{
"mappings": {
"_meta": {
"software_version_mapping": "1.0"
}
}
}

规范

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
1、不允许自动新增字段,将 dynamic 设置成 strict。默认为 true;

2、不需要分词的字段,将 type 设置成 keyword。默认使用了多字段特性,text、keyword这2种类型都有;

3、不需要检查的字段,将 index 设置成 false。默认为 true;

4、不需要排序和聚合的字段,将 doc_values 设置成false。默认为 true;

5、不需要检查、排序、聚合的字段,将 enable 设置成 false,仅做存储;

6、type = text 的字段,默认不可以排序,如需要排序,将 fielddata 设置成 true,默认为 false;

7、单个索引避免过多字段,默认最大值为1000;

8、避免空值引起的聚合不准确的问题;

9、避免使用正则查询;

10、尽量不要设计成索引关联,可冗余多一些字段,以空间换时间