目录
解决方案: Nested Object & Key Value
建模建议(五):为索引的 Mapping 加⼊ Meta 信息
建模建议(一):如何处理关联关系
- 优先考虑Denormalization
- 当数据包含多数值对象(多个对象),同时有查询需求考虑Nested
- 关联文档更新非常频繁考虑Child/parent
建模建议(二):
- 一个文档中,最好避免大量的字段
- 过多的字段数不容易维护
- Mapping信息保存早Cluster State中,数据量过大,对集群性能会有影响(Cluster State信息需要和所有的节点同步)
- 删除或者修改需要reindex
- 默认的最大字段数是1000,可以设置Index.mapping.total_fields.limit限定最大子段数.
- 什么原因会导致文档中有成百上千的字段???
Dynamic VS Strict
- Dynamic(生产环境中,尽量不要打开Dynamic )
- true-位置字段会被自动加入
- false-新字段不会被索引,但是会保存在_souce
- strict-新增字段不会被索引,稳当写入失败
- Strict
- 可以控制在字段级别
一个例子:Cookie Server的数据
-
来自Cookie Service的数据
-
Cookie的键值对很多
-
当Dynamic设置为True同时采用扁平化的设计,必然导致字段数量的膨胀
-
解决方案: Nested Object & Key Value
- name:用来保存key
- xxxxValue用来保存对应的value
- "login":"2011-22-12"
- "name":"login" "dataValue":"2011-22-12"
#使用 Nested 对象,增加key/value
PUT cookie_service
{
"mappings": {
"properties": {
"cookies": {
"type": "nested",
"properties": {
"name": {
"type": "keyword"
},
"dateValue": {
"type": "date"
},
"keywordValue": {
"type": "keyword"
},
"IntValue": {
"type": "integer"
}
}
},
"url": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
}PUT cookie_service/_doc/1
{
"url":"www.google.com",
"cookies":[
{
"name":"username",
"keywordValue":"tom"
},
{
"name":"age",
"intValue":32}
]
}
PUT cookie_service/_doc/2
{
"url":"www.amazon.com",
"cookies":[
{
"name":"login",
"dateValue":"2019-01-01"
},
{
"name":"email",
"IntValue":32}
]
}
#使用nested对象保存key和value
优点
可以减少字段数量,解决Cluster State中保存过多Meta信息的问题
缺点
导致查询语句复杂度增加
Nested对象,不利于在Kibanan中实现可视化分析
POST cookie_service/_search
{
"query": {
"nested": {
"path": "cookies",
"query": {
"bool": {
"filter": [
{
"term": {
"cookies.name": "age"
}
},
{
"range": {
"cookies.intValue": {
"gte": 30
}
}
}
]
}
}
}
}
}
建模建议(三):避免正则查询
-
问题:
-
正则,通配符查询,前缀查询属于Term查询,但是性能不够好
-
特别是将通配符放在开头,会导致性能的灾难
-
-
案例
-
文档中某个字段包含了ES的版本信息,例如:version:"7.1.0"
-
搜索所有是 bug fix的版本?每个版本号所关联的文档
-
解决方案:将字符串转换为对象
# 优化,使用inner object
PUT softwares/
{
"mappings": {
"_meta": {
"software_version_mapping": "1.1"
},
"properties": {
"version": {
"properties": {
"display_name": {
"type": "keyword"
},
"hot_fix": {
"type": "byte"
},
"marjor": {
"type": "byte"
},
"minor": {
"type": "byte"
}
}
}
}
}
}
PUT softwares/_doc/1
{
"version":{
"display_name":"7.1.0",
"marjor":7,
"minor":1,
"hot_fix":0
}}
PUT softwares/_doc/2
{
"version":{
"display_name":"7.2.0",
"marjor":7,
"minor":2,
"hot_fix":0
}
}POST softwares/_search
{
"query": {
"bool": {
"filter": [
{
"match":{
"version.marjor":7
}
},
{
"match":{
"version.minor":2
}
}]
}
}
}
建模建议(四):避免空值引起的聚合不准
解决方法
#Not Null 解决聚合的问题:为null指定一个默认值
{ "mappings": {
"properties": {
"rating": {
"type": "float",
#为空
"null_value": 1.0
}
}
}
}
建模建议(五):为索引的 Mapping 加⼊ Meta 信息
-
Mappings设置非常重要,需要从两个维度进行考虑
-
功能: 搜索,聚合,排序
-
性能:存储的开销;内存的开销;搜索的性能
-
-
Mappings设置是一个迭代的过程
-
加入新的字段很容易(必要时需要update_by_query)
-
更新删除字段不允许(需要Reindex重建数据)
-
最好能对Mappings加入Meta信息,更好的进行版本管理
-
可以考虑将Mapping文件上传git进行管理
-