学会这个ES数据建模指南,还需要啥MySQL?( 五 )


"type":"keyword",
"ignore_above":256
}
}
}
}
}
}
POSTmix_index/_search
{
"query":{
"bool":{
"should":[
{
"match_phrase":{
"content":"佟大"
}
},
{
"match_phrase":{
"content.standard":"佟大"
}
}
]
}
}
}
为了方便你记忆和使用 , 这里我把字段细节总结在如下这张表格中 。
学会这个ES数据建模指南,还需要啥MySQL?
文章图片
我们再来分析一下数据建模的流程 , 如下图所示 。
学会这个ES数据建模指南,还需要啥MySQL?
文章图片
数据建模的流程图
首先 , 根据业务选择合适的数据类型 。
注意字符串类型分为两种text和keyword类型;尽量选择贴近实际大小的数据类型;nested和join复杂类型需根据业务特点选型 , 具体会在下一部分详细阐述 。
其次 , 判定是否需要检索 , 如果不需要 , index设置为false即可 。
然后 , 判定是否需要排序和聚合操作 , 如果不需要可以设置doc_values为false 。
最后 , 考虑一下是否需要另行存储 , 会结合使用store和_source字段 。
Mapping层面要强调的是:尽量不要使用默认的dynamic动态字段类型 , 强烈建议strict严格控制字段 , 避免字段“暴涨”导致不可预知的风险 , 比如字段数超过默认1000个的上限、磁盘大于预期的激增等 。
5、基于复杂索引关联建模
要摒弃MySQL的多表关联建模思想 , 因为MySQL中的范式思想都不再适用于Elasticsearch 。 回顾文章开头的几个多表关联问题 , Elasticsearch能提供的核心解决方案如下 。
1)宽表方案
这是空间换时间的方案 , 就是允许部分字段冗余存储的存储方式 。 实战举例如下 。
用户索引:user 。
博客索引:blogpost 。
一个用户可以发表多篇博客 。 按照传统的MySQL建表思想:两个表建立个用户外键 , 即可搞定一切 。 而对于Elasticsearch , 我们更愿意在每篇博文后面都加上用户信息(这就是宽表存储的方案) , 看似存储量大了 , 但是一次检索就能搞定搜索结果 。
PUTuser/_doc/1
{
"name":"JohnSmith",
"email":"john@smith.com",
"dob":"1970/10/24"
}
PUTblogpost/_doc/2
{
"title":"Relationships",
"body":"It'scomplicated...",
"user":{
"id":1,
"name":"JohnSmith"
}
}
GET/blogpost/_search
{
"query":{
"bool":{
"must":[
{
"match":{
"title":"relationships"
}
},
{
"match":{
"user.name":"John"
}
}
]
}
}
}
2)nested方案适用场景:1对少量 , 子文档偶尔更新、查询频繁的场景 。
如果需要索引对象数组并保持数组中每个对象的独立性 , 则应使用嵌套Nested数据类型而不是对象Oject数据类型 。
nested文档的优点是可以将父子关系的两部分数据(如博客+评论)关联起来 , 我们可以基于nested类型做任何的查询 。 但缺点是查询速度相对较慢 , 更新子文档需要更新整篇文档 。
3)join父子文档方案适用场景:子文档数据量要明显多于父文档的数据量 , 存在1对多量的关系;子文档更新频繁的场景 。
比如1个产品和供应商之间就是1对N的关联关系 。 当使用父子文档时 , 使用has_child或者has_parent做父子关联查询 。 优点是父子文档可独立更新 , 但维护Join关系需要占据部分内存 , 查询较Nested更耗资源 。
注意:5.X之前版本叫父子文档(多type实现) , 6.X之后高版本是join类型(单type类型) 。