笔记四十六:Elasticsearch 数据建模实例
什么是数据建模
- 数据建模(Data modeling),是创建数据模型的过程。
- 数据模型是对真实世界进行抽象描述的一种工具和方法,实现对现实世界的映射
- 博客、作者、用户评论
- 三个过程:概念模型 =》逻辑模型 =》数据模型(第三范式)
- 数据模型:结合具体的数据库,在满足业务读写性能等需求的前提下,确定最终的定义
- 数据模型是对真实世界进行抽象描述的一种工具和方法,实现对现实世界的映射
数据建模:功能需求 + 性能需求
如何对字段进行建模
字段类型 : Text v.s 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_ordinals 设置为 true
额外的存储
- 是否需要专门存储当前字段数据
- Store 设置为 true ,可以存储该字段的原始数据
- 一般结合 _source 的 enabled 为 false 时候使用
- Disable_source : 节约磁盘,适用于指标型数据
- 一般建议先考虑增加压缩比
- 无法看到 _source 字段,无法做 ReIndex,无法做 Update
- Kibana 中无法做 discovery
一个数据建模的实例
- 图书的索引
- 书名
- 简介
- 作者
- 发行日期
- 图书封面
PUT books/_doc/1
{
"title":"Mastering ElasticSearch 5.0",
"description":"Master the searching, 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-na.ssl-images-amazon.com/images/I/51OeaMFxcML.jpg"
}
GET books/_mapping
# return
{
"books" : {
"mappings" : {
"properties" : {
"author" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"cover_url" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"description" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"public_date" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"title" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
}
}
}
优化字段的设定
- 图书的索引
- 书名:支持全文和精确匹配
- 简介:支持全文
- 作者:精确值
- 发行日期:日期类型
- 图书封面:精确值
#优化字段类型
PUT books
{
"mappings" : {
"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
}
}
}
}
}
}
#Cover URL index 设置成false,无法对该字段进行搜索
POST books/_search
{
"query": {
"term": {
"cover_url": {
"value": "https://images-na.ssl-images-amazon.com/images/I/51OeaMFxcML.jpg"
}
}
}
}
#Cover URL index 设置成false,依然支持聚合分析
POST books/_search
{
"aggs": {
"cover": {
"terms": {
"field": "cover_url",
"size": 10
}
}
}
}
需求变更
- 新需求:增加图书内容的字段,并要求能被搜索同时支持高亮显示
- 新需求会导致 _source 的内容过大
- Source Filtering 只是传输给客户端进行过滤, Fetch 数据时, ES 节点还是会传输 _source 中的数据
- 解决方法
- 关闭 _source
- 然后将每个字段的 “store” 设置成 true
DELETE books
#新增 Content字段。数据量很大。选择将Source 关闭
PUT books
{
"mappings" : {
"_source": {"enabled": false},
"properties" : {
"author" : {"type" : "keyword","store": true},
"cover_url" : {"type" : "keyword","index": false,"store": true},
"description" : {"type" : "text","store": true},
"content" : {"type" : "text","store": true},
"public_date" : {"type" : "date","store": true},
"title" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 100
}
},
"store": true
}
}
}
}
查询图书:解决字段过大引发的性能问题
- 返回结果不包含 _source 字段
- 对于需要显示的信息,可以在查询中指定 “store_fields”
- 禁止 _source 字段后,还是支持使用 hignlights API ,高亮显示 content 中的匹配的相关信息
# Index 一本书的信息,包含Content
PUT books/_doc/1
{
"title":"Mastering ElasticSearch 5.0",
"description":"Master the searching, indexing, and aggregation features in ElasticSearch Improve users’ search experience with Elasticsearch’s functionalities and develop your own Elasticsearch plugins",
"content":"The content of the book......Indexing data, aggregation, searching. something else. something in the way............",
"author":"Bharvi Dixit",
"public_date":"2017",
"cover_url":"https://images-na.ssl-images-amazon.com/images/I/51OeaMFxcML.jpg"
}
#查询结果中,Source不包含数据
POST books/_search
{}
#搜索,通过store 字段显示数据,同时高亮显示 conent的内容
POST books/_search
{
"stored_fields": ["title","author","public_date"],
"query": {
"match": {
"content": "searching"
}
},
"highlight": {
"fields": {
"content":{}
}
}
}
Mapping 字段的相关设置
- https://www.elastic.co/guide/en/elasticsea...
- Enabled
- Index
- Norms
- Doc_values
- Field_data
- Store
- Coerce
- Multifields
- Dynamic
一些相关的 API
- Index Template & Dynamic Template
- 根据索引的名字匹配不同的 Mappings 和 Settings
- 可以在⼀个 Mapping 上动态的设定字段类型
- Index Alias
- ⽆需停机,⽆需修改程序,即可进⾏修改
- Update By Query & Reindex
- 数据建模对功能与性能⾄关重要
本章知识点
- 数据建模对功能与性能⾄关重要
- Mapping. & Setting
- 字段 Mapping 参数的⼀些回顾,分⽚的设定,会在后续讲解
- 通过具体的实例,学习了数据建模时需要考虑的点
- 确定字段类型
- 是否需要搜索和聚合以及排序
- 是否需要禁⽌ _source 以及打开 store
本作品采用《CC 协议》,转载必须注明作者和本文链接