建模建议(一):如何处理关联关系

建模优先级
普通对象 --> 嵌套对象 --> 父子对象
Kibana.....
- kibana目前暂不支持nested类型和parent/child类型,在未来有可能会支持
- 如果需要使用kibana进行数据分析,在数据建模时仍需对嵌套和父子关联类型做出取舍
建模建议(二):避免过多字段
- 一个文档中,最好避免大量的字段
- 过多的字段数不容易维护
- Mapping信息保存在Cluster State中,数据量过大,对集群性能会有影响(Cluster State信息需要和所有的节点同步)
- 删除或者修改数据需要reindex
- 默认最大字段数是1000,可以设置index.mapping.total.fields.limit限定最大字段数
- 什么原因会导致文档中有成百上千的字段?
Dynamic v.s Strict
- Dynamic(生产环境中,尽量不要打开Dynamic)
- true:未知字段会被自动加入
- false:新字段不会被索引,但是会保存在_source中
- strict:新增字段不会被索引,文档写入失败
- Strict
- 可以控制到字段级别
- 一个例子:Cookie Service的数据
- 来自Cookie Service的数据
- Cookie的键值对很多
- 当Dynamic设置为true
- 同时 采用扁平化的设计,必然导致字段数量的膨胀
- 解决方案:Nested Object & Key Value
- 来自Cookie Service的数据
PUT cookie_service
{
"mappings": {
"properties": {
"cookies": {
"type": "nested",
"properties": {
"name": {
"type": "keyword"
},
"dateValue": {
"type": "date"
},
"keywordValue": {
"type": "keyword"
},
"intValue": {
"type": "integer"
}
}
},
"url": {
"type": "keyword"
}
}
}
}
通过Nested对象保存key/value的一些不足
- 可以减少字段数量,解决Cluster State中保存过多Meta信息的问题,但是
- 导致查询语句复杂度增加
- Nested对象,不利于在Kibana中实现可视化分析
建模建议(三):避免正则查询
- 问题:
- 正则:通配符查询,前缀查询属于Term查询,但是性能不够好
- 特别是将通配符放在开头,会导致性能的灾难
- 案例:
- 文档中某个字段包含了Elasticsearch的版本信息,例如:version:"7.1.0"
- 搜索所有是bugfix的版本?每个主要版本号所关联的文档?
解决方案:将字符串转换为对象
可以将版本转换为:display_name、hot_fix、marjor、minor来对日志进行存储,从而达到相应的查询高效性
建模建议(四):避免空值引起的聚合不准

null值聚合不准确
解决方案:

设置mapping
建模建议(五):为索引的Mapping加入Meta信息
- Mappings设置非常重要,需要从两个维度进行考虑
- 功能:搜索,聚合,排序
- 性能:存储的开销;内存的开销;搜索的性能
- Mappings设置是一个迭代的过程
- 加入新的字段很容易(必要时需要update_by_query)
- 更新删除字段不允许(需要Reindex重建数据)
- 最好能对Mappings加入Meta信息,更好的进行版本管理
- 可以考虑将Mapping文件上传git进行管理

为mapping加入meta信息