# Elasticsearch 开发规范

整理 版本 日期 描述
驴打滚 0.0.1 2023.02.22 初稿

# 命名

  • 索引index命名

    • 名称全部小写
    • 多个单词,以“_”(下划线)分隔
    • 别名 (opens new window),为索引指定别名;应用中使用别名而不是索引名,可以在任何时候重建索引
  • 类型type命名

    • 名称全部小写
    • 多个单词,以“_”(下划线)分隔
  • 字段field命名

    • 名称全部小写
    • 多个单词,以“_”(下划线)分隔

# 配置

  • 索引(建议)
    • 为了减少索引数量并避免非常庞大的映射,请考虑将相同索引结构的数据存储在相同的索引中
    • 避免将不相关的数据放在同一个索引中,以避免稀疏,将这些文件放在不同的索引中往往更好

此建议不适用于您需要使用文档之间的 parent / child 关系的情况,因为该功能仅在同一索引中的文档支持

  • 容量、Shard划分策略(建议)
    • 每个分片都可以处理索引和查询请求
      • 建议单个分片最大容量不超过30GB
      • 根据索引预计承载的最大数据容量和单个分片容量确定主分片个数
      • 为了提升数据可靠性,合理设置副本分片个数

主分片个数一旦确定,就不可以更改。副本分片个数可以根据需要随时修改。

  • 分析器

    • 根据业务分词搜索需要,在index建立时配置合适的分析器(字符过滤器、分词器、词单元过滤器)
    • 通常中文分词选择ik分词器即可满足
  • 字段

    • 禁止包含未涉及全文检索和聚合分析的字段,如业务需要,可二次查询MySQL进行提取
    • 不需要搜索object字段(任意json对象)设置enabled=false
    • 不需要搜索但有类型的字段设置index=no

# 关联关系

# 实现方案如下:

  • 应用端关联

    • 适用场景:数据量少的业务场景
    • 存储层面:独立两个索引存储
    • 实际业务层面分两次请求,将第一次查询结果和第二次查询结果组合后,返回给用户
    • 优点:数据量少时,用户体验好
    • 缺点:数据量大,两次查询耗时肯定会比较长,影响用户体验
  • 宽表冗余存储

    • 适用场景:一对多或者多对多关联
    • 官方文档中的“Data denormalization”,通俗解释就是:冗余存储,对每个文档保持一定数量的冗余数据可以在需要访问时避免进行关联
    • 通过logstash 同步关联数据到ES时,通常会建议:先通过视图对Mysql数据做好多表关联,然后同步视图数据到ES。此处的视图就是宽表
    • 优点:速度快。因为每个文档都包含了所需的所有信息,当这些信息需要在查询进行匹配时,并不需要进行昂贵的关联操作
    • 缺点:索引更新或删除数据,应用程序不得不处理宽表的冗余数据;由于冗余存储,导致某些搜索和聚合操作可能无法按照预期工作
  • 嵌套文档(Nested)存储

    • 适用场景:
      • 1)对少量,子文档偶尔更新、查询频繁的场景。
      • 2)需要索引对象数组并保持数组中每个对象的独立性,则应使用嵌套 Nested 数据类型而不是对象 Object 数据类型
    • Nested类型是ES Mapping定义的集合类型之一,它是比object类型更NB的支持独立检索的类型
    • 优点:nested文档可以将父子关系的两部分数据(举例:博客+评论)关联起来,可以基于nested类型做任何的查询
    • 缺点:查询相对较慢,更新子文档需要更新整篇文档
  • 父子文档存储

    • 适用场景:子文档数据量要明显多于父文档的数据量,存在1 对多量的关系;子文档更新频繁的场景
    • 6.X之前的版本的父子文档存储在相同索引的不同type中。而6.X之上的版本,单索引下已不存在多type的概念。父子文档Join的都是基于相同索引相同type实现的
    • join类型是ESMapping定义的类型之一,用于在同一索引的文档中创建父/子关系。 关系部分定义文档中的一组可能关系,每个关系是父名称和子名称
    • 优点:父子文档可独立更新
    • 缺点:维护Join关系需要占据部分内存,查询较Nested更耗资源

在Elasticsearch开发实战中对于多表关联的设计要突破关系型数据库设计的思维定式,不建议在es做join操作,parent-child能实现部分功能,但是它的开销比较大,如果可能,尽量在设计时使用扁平的文档模型。尽量将业务转化为没有关联关系的文档形式,在文档建模处多下功夫,以提升检索效率 Nested&Join父子文选型必须考虑性能问题。 nested 类型检索使得检索效率慢几倍,父子Join 类型检索会使得检索效率慢几百倍。

# 索引数据

  • 写入

    • bulk API把多个单条的记录合并成一个大数组统一提交,这样避免一条条发送的header解析,索引频繁更新
  • 读取

    • 搜索结果不要返回过大的结果集
    • 不要在一次query中设置过大的size参数

如要做大批量结果的查询,记得考虑用scroll api。