51 - Elasticsearch数据建模

什么是数据建模

  • 数据建模(Data modeling),是创建数据模型的过程
    • 数据模型是对真实世界进行抽象描述的一种工具和方法,实现对现实世界的映射
      • 博客 / 作者 / 评论
    • 三个过程:模型概念 => 逻辑模型 => 数据模型(第三范式)
      • 数据模型:结合具体的数据库,在满足业务读写性能需求的前提下,确定最终的定义

数据建模:功能需求 + 性能需求

数据建模示意图

需考虑模型的功能需求和性能需求

如何对字段进行建模

  • 字段类型
  • 是否要搜索及分词
  • 是否要聚合及排序
  • 是否要额外的存储

字段类型: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_values / fielddata 设置为false
  • 更新频繁,聚合查询频繁的keyword类型的字段
    • 推荐将eager_global_oridinals设置为true

额外的存储

  • 是否需要专门存储当前字段数据
    • Store设置为true,可以存储该字段的原始内容
    • 一般结合_source的enabled为false时候使用
  • Disable _source:节约磁盘;适用于指标型数据
    • 一般建议先考虑增加压缩比
    • 无法看到_source字段,无法做ReIndex,无法做Update

一个数据建模的实例

  • 图书的索引
    • 书名
    • 简介
    • 作者
    • 发行日期
    • 图书封面
PUT book/_doc/1
{
  "title": "mastering elasticsearch 5.0",
  "description": "master the search indexing, and aggregation features in elasticsearch Improve users search experience with elasticsearch`s functionalities and develop your own elasticsearch plugins",
  "author": "Bharvi Dixit",
  "public_date": "2017",
  "cover_url": "https://images.xxx.com/images/1/xxxx.jpg"
}
默认文本mapping

优化字段设定

  • 图书的索引
    • 书名:支持全文和精确匹配
    • 简介:支持全文
    • 作者:精确值
    • 发型日期:日期类型
    • 图书封面:精确值
修正后mapping

封面无需索引,index可以设置为false


对封面搜索报错
支持进行聚合

需求变更

  • 新需求:增加图书内容的字段。并要求能被搜索同时,支持高亮显示
  • 新需求会导致_source的内容过大
    • Source Filtering只是传输给客户端时进行过滤,Fetch数据时,ES节点还是会传输_source中的数据
  • 解决方法
    • 关闭_source
    • 然后将每个字段的“store”设置为true
      mapping更新如下:
PUT books
{
  "mappings": {
    "_source": {"enabled": false},
    "properties": {
      "author": {
        "type": "keyword"
      },
      "cover_url": {
        "type": "keyword",
        "index": false
      },
      "description": {
        "type": "text"
      },
      "public_date": {
        "type": "date"
      },
      "title": {
        "type": "text",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 100
          }
        },
        "store": true
      },
      "content": {
        "type": "text",
        "store": true
      }
    }
  }
}

查询图书:解决字段过大引发的性能问题

  • 返回结果不包含_source字段
  • 对于需要显示的信息,可以在查询中指定“stored_fields”
  • 禁止_source字段后,还是支持使用highlights API高亮,高亮显示content中匹配的相关信息
查询示例

Mapping字段的相关设定

  • https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-params.html
    • Enabled:设置为false,仅做存储,不支持搜索和聚合分析(数据保存在_source中)
    • Index:是否构倒排索引。设置为false,无法被搜索,但还是支持aggregation,并出现在_source中
    • Norms:如果字段用来过滤和聚合分析,可以关闭,节约存储
    • Doc_values:是否启用doc_values,用于排序和倒排分析
    • field_data:如果要对text类型启用排序和聚合分析,fielddata需要设置成true
    • Store:默认不存储,数据默认存储在_source中
    • Coerce:默认开启,是否开启数据类型的自动转换(例如:字符串转数字)
    • Multifields:多字段特性
    • Dynamic:true / false / strict控制Mapping的自动更新

一些相关api

  • Index Template & Dynamic Template
    • 根据索引的名字匹配不同的Mappings和Settings
    • 可以在一个Mapping上动态的设定字段类型
  • Index Alias
    • 无需停机,无需修改程序,即可进行修改
  • Update by query & Reindex
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容