共计 2268 个字符,预计需要花费 6 分钟才能阅读完成。
如何处理关联关系
- Kibana 目前暂时不支持 nested 类型和 parent/child 类型,在未来有可能会支持,在 Kibana 界面上展示数据的时候不是很友好
- 如果需要使用 Kibana 进行数据分析,在建模时需要对嵌套和父子类型进行取舍
避免过多字段
- 过多字段不好维护
- Mapping 信息保存在 Cluster State 中,数据量过大,对集群性能有影响(Cluster State 信息需要和所有节点同步)
- 删除或者修改数据需要 reindex.
- 默认最大字段数是 1000,可以设置 index.mapping.total_fields.limt 限定最大字段数
- 生产环境尽量不要打开 Dynamic Dynamic Mapping
- 考虑下这样一个场景,
## 索引数据,dynamic mapping 会不断加入新增字段
PUT cookie_service/_doc/1
{
"url":"www.google.com",
"cookies":{
"username":"tom",
"age":32
}
}
PUT cookie_service/_doc/2
{
"url":"www.amazon.com",
"cookies":{
"login":"2019-01-01",
"email":"xyz@abc.com"
}
}
我们的 cookie 字段使用了 Dynamic=true
默认值,所以随着写入的数据越来越多,如果不对 cookies 字段的子字段进行限制的话,字段数会越来越多,会影响性能,
- 解决方案
# 使用 Nested 对象,增加 key/value
PUT cookie_service
{
"mappings": {
"dynamic": "strict",
"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
}
}
}
}
}
}
需要说明几点的是:
- 设置
"dynamic": "strict"
阻止其他字段加入 - 通过 name 和 dateValue, keywordValue, IntValue 这样的设计可以存储任意的 key-value
避免正则查询
正则查询的性能不够好,前缀查询属于 Term 查询
- 案例如下:
文档中某个字段包含了 Elasticsearch 的版本信息,例如 version: “7.1.0”, 现在我们需要查询朱版本是 7,次要版本是 2 的文档,不要使用正则查询
- 解决方案如下: 我们使用 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"}
}
}
}
}
}
然后我们再使用查询
POST softwares/_search
{
"query": {
"bool": {
"filter": [
{
"match":{"version.marjor":7}
},
{
"match":{"version.minor":2}
}
]
}
}
}
避免空值引起的聚合不准
- 首先我们先看一下示例
PUT ratings/_doc/1
{"rating":5}
PUT ratings/_doc/2
{"rating":null}
POST ratings/_search
{
"size": 0,
"aggs": {
"avg": {
"avg": {"field": "rating"}
}
}
}
# 查询结果
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : null,
"hits" : []},
"aggregations" : {
"avg" : {"value" : 5.0}
}
}
很明显,我们查到了两条数据,但是平均值是 5,这个很难以理解,
- 解决方案,我们给 null 值设置一个默认值
PUT ratings
{
"mappings": {
"properties": {
"rating": {
"type": "float",
"null_value": 0
}
}
}
}
再次插入上面的数据,我们得到下面的结果
{
"took" : 5,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : null,
"hits" : []},
"aggregations" : {
"avg" : {"value" : 2.5}
}
}
这样就比较对了,当然 null_value
的值是可以自己根据业务需求自己设定的
正文完
发表至:无分类
2019-08-29