8 Elasticsearch 篇之数据建模

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/bingdianone/article/details/86611990

数据建模简介

数据建模

·英文为Data Modeling ,为创建数据模型的过程
·数据模型( Data Model )

  • 对现实世界进行抽象描述的一种工具和方法
  • 通过抽象的实体及实体之间联系的形式去描述业务规则,从而实现对现实世界的映射

数据建模的过程

.概念模型

  • 确定系统的核心需求和范围边界,设计实体和实体间的关系

·逻辑模型

  • 进一步梳理业务需求,确定每个实体的属性、关系和约束等

·物理模型

  • 结合具体的数据库产品,在满足业务读写性能等需求的前提下确定最终的定义
  • mysql,MongoDB,elasticsearch等
  • 第三范式

数据建模的意义

在这里插入图片描述

ES数据建模配置相关介绍

ES是基于Lucene以倒排索引为基础实现的存储体系,不遵循关系型数据库中的范式约定
在这里插入图片描述

Mapping字段的相关设置

enabled

  • true | false
  • 仅存储,不做搜索或聚合分析

. index

  • true | false
  • 是否构建倒排索引

index_options

  • docs | freqs I positions | offsets
  • 存储倒排索引的哪些信息

norms

  • true | false
  • 是否存储归一化相关参数,如果字段仅用于过滤和聚合分析,可关闭

doc values

  • true | false
  • 是否启用doc values ,用于排序和聚合分析

field data

  • false I true
  • 是否为text类型启用fielddata ,实现排序和聚合分析

store

  • false | true
  • 是否存储该字段值

coerce

  • true l false
  • 是否开启自动数据类型转换功能,比如字符串转为数字、浮点转为整型等

multifields多字段

  • 灵活使用多字段特性来解决多样的业务需求

dynamic

  • true | false | strict
  • 控制mapping自动更新

date_detection

  • true I false
  • 是否自动识别日期类型

Mapping字段属性的设定流程

在这里插入图片描述

是何种类型?

·字符串类型

  • 需要分词则设定为text类型,否则设置为keyword类型

·枚举类型

  • 基于性能考虑将其设定为keyword类型,即便该数据为整型

·数值类型

  • 尽量选择贴近的类型,比如byte即可表示所有数值时,即选用byte ,不要用long

·其他类型

  • 比如布尔类型、日期、地理位置数据等

是否需要检索

完全不需要检索、排序、聚合分析的字段

  • enabled设置为false

不需要检索的字段

  • index设置为false

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

  • index-options结合需要设定
  • norms不需要归一化数据时关闭即可

是否需要排序和聚合分析

不需要排序或者聚合分析功能

  • doc values设定为false
  • fielddata设定为false

是否需要另行存储?

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

  • store设定为true ,即可存储该字段的原始内容(与_source中的不相关)
  • 一般结合_source的enabled设定为false时使用

ES数据建模实例

·博客文章 blog_index

  • 标题title
  • 发布日期publish-date
  • 作者author
  • 摘要abstract
  • 网络地址url

blog_index的mapping设置如下:
在这里插入图片描述
加了一个字段:
博客文章 blog_index

  • 标题title
  • 发布日期publish-date
  • 作者author
  • 摘要abstract
  • 内容 content(非常大)
  • 网络地址url

blog_index的mapping设置如下(都加了store:true专门存储每个字段原始值;不存入_source中了):
在这里插入图片描述
查询不返回content
在这里插入图片描述

Nested_Object

关联关系处理

.ES不擅长处理关系型数据库中的关联关系,比如文章表blog与评论表comment之间通过blogid关联,在ES中可以通过如下两种手段变相解决

  • Nested Object
  • Parent/Child

·评论Comment

  • 文章Id blog-id
  • 评论人username
  • 评论日期date
  • 评论内容content

关系型数据库中的设计:
在这里插入图片描述

关联关系处理之Nested Object

ES中的设计:
在这里插入图片描述
问题:查询结果不是预期的
在这里插入图片描述
Comments默认是Object Array ,存储结构类似下面的形式:

在这里插入图片描述
Nested Object可以解决这个问题:
在这里插入图片描述
再次进行查询即是我们想要的结果:
在这里插入图片描述
Nested Object Array的存储结构类似下面的形式:可以解决这个问题
在这里插入图片描述

Parent_Child

ES还提供了类似关系数据库中join的实现方式,使用join数据类型实现
在这里插入图片描述

关联关系处理之Parent/Child

在这里插入图片描述
常见 query语法包括如下几种:

  • parent_id返回某父文档的子文档
  • has_child返回包含某子文档的父文档
  • has_parent返回包含某父文档的子文档

-parent_id返回某父文档的子文档
在这里插入图片描述
-has_child返回包含某子文档的父文档
在这里插入图片描述
-has_parent返回包含某父文档的子文档
在这里插入图片描述

nested_vs_parent_child

在这里插入图片描述

reindex

指重建所有数据的过程,一般发生在如下情况:

  • mapping设置变更,比如字段类型变化、分词器字典更新等
  • index设置变更,比如分片数更改等
  • 迁移数据

ES提供了现成的API用于完成该工作

  • update-by.query在现有索引上重建
  • _reindex在其他索引上重建

Reindex-_update_by_query

https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-update-by-query.html
在这里插入图片描述

Reindex-_reindex

在这里插入图片描述
在这里插入图片描述

Reindex-Task

数据重建的时间受源索引文档规模的影响,当规模越大时,所需时间越多,此时需要通过设定url参数wait_for_completion为false来异步执行, ES以task来描述此类执行任务.

ES提供了Task API来查看任务的执行进度和相关数据
在这里插入图片描述

其他建议

对Mapping进行版本管理

  • 包含在代码或者以专门的文件进行管理,添加注释,并加入Git等版本管理仓库中,方便回顾
  • 为每个增加一个metadata字段,在其中维护一些文档相关的元数据,方便对数据进行管理

在这里插入图片描述

防止字段过多

·字段过多主要有如下的坏处:

  • 难于维护,当字段成百上千时,基本很难有人能明确知道每个字段的含义
  • mapping的信息存储在cluster state里面,过多的字段会导致mapping过大,最终导致更新变慢

·通过设置index.mapping.total_fields.limit可以限定索引中最大字段数,默认是1000
·可以通过key/value的方式解决字段过多的问题,但并不完美

key/value的方式详解

设置变化
在这里插入图片描述
字段会变少:
在这里插入图片描述
查询会变得复杂:
在这里插入图片描述
虽然通过这种方式可以极大地减少Field数目,但也有一些明显的坏处

  • query语句复杂度飙升,且有一些可能无法实现,比如聚合分析相关的
  • 不利于在Kibana中做可视化分析

防止字段过多

·一般字段过多的原因是由于没有高质量的数据建模导致的,比如dynamic设置为true
·考虑拆分多个索引来解决问题

猜你喜欢

转载自blog.csdn.net/bingdianone/article/details/86611990