elasticsearch - 弹性:我如何通过字符串键过滤聚合桶
问题描述
我有来自一个提供商的一些数据 - 非常大的结构化 JSON 数据:
"mappings": {
"properties": {
"field_a": { .. },
"field_b": { .. },
"field_c": { .. },
"field_d": {
"properties": {
"subfield_a": {...},
"subfield_b": {...},
"subfield_c": {...},
"subfield_d": {...},
"subfield_e": {
"properties": {
"myfield": {
"type": "keyword"
},
"another_a": {...},
"another_b": {...},
}
}
}
}
}
}
subfield_e 是对象数组,包含许多我感兴趣的字段“myfield”。
我只需要聚合包含一些字符串的字段“myfield”。
所以,我现在这样做是错误的(但逻辑结果):
GET /index/_search
{
"query": {
"wildcard": {
"field_d.subfield_e.myfield": "*string*"
}
},
"aggs": {
"interest": {
"terms": {
"field": "field_d.subfield_e.myfield",
"size": 10
}
}
},
"size": 0
}
该查询的问题是,该查询将选择对象数组“esubfield_e”包含带有字符串的对象 myfield 的所有文档,并在这些文档下进行聚合。所以,最后我得到了这些文档下所有“myfields”的结果,而不仅仅是包含string的 myfields 。
我试图在我的主要聚合之后进行 bucket_selector 聚合,但我得到了错误:“buckets_path 必须引用一个数字值或一个单值数字度量聚合,得到:聚合 [_key] 处的 [String]”
我的代码的灵感来自:Filter Elasticsearch Aggregation by Bucket Key Value ,现在看起来:
GET /index/_search
{
"query": {
"wildcard": {
"field_d.subfield_e.myfield": "*string*"
}
},
"aggs": {
"interest": {
"terms": {
"field": "field_d.subfield_e.myfield",
"size": 10
}
},
"aggs": {
"buckets": {
"bucket_selector": {
"buckets_path": {
"key": "_key"
},
"script": "params.key.contains('string')"
}
}
}
}
},
"size": 0
}
那么,我如何通过它们的字符串键过滤聚合桶(术语 aggs)?
解决方案
我通过将 subfield_e 切换到嵌套对象而不是未定义数组来解决它,并将所有数据重新导入到这个新映射中。
当前映射如下所示:
"mappings": {
"properties": {
"field_a": { .. },
"field_b": { .. },
"field_c": { .. },
"field_d": {
"properties": {
"subfield_a": {...},
"subfield_b": {...},
"subfield_c": {...},
"subfield_d": {...},
"subfield_e": {
"type": "nested" <======= This line added
"properties": {
"myfield": {
"type": "keyword"
},
"another_a": {...},
"another_b": {...},
}
}
}
}
}
}
最后的工作查询是:
GET /index/_search
{
"query": {
"nested": {
"path": "field_d.subfield_e",
"query": {
"wildcard": {
"field_d.subfield_e.myfield": {
"value": "*string*"
}
}
}
}
},
"aggs": {
"agg": {
"nested": {
"path": "field_d.subfield_e"
},
"aggs": {
"inner": {
"filter": {
"wildcard": {
"field_d.subfield_e.myfield": "*string*"
}
}, "aggs": {
"interest": {
"terms": {
"field": "field_d.subfield_e.myfield",
"size": 10
}
}
}
}
}
}
},
"size": 0
}
在我的情况下,此查询的速度比在术语聚合中使用包含/排除要好得多。
推荐阅读
- java - PriorityQueues 中的元素何时排序?
- dart - 如何将数据从 channel.dart 传递到中间件句柄方法?
- java - 创建一个 CSV 文件并将其从 lambda 函数上传到 AWS S3 存储桶
- makefile - 在 ubuntu 18.04 LTS 上安装 caffe
- android - 如何从firebase实时数据库中读取所有键中的数据
- plot - 用 Gtk Vala 构建图表?
- c# - C# JsonConvert.DeserializeObject 没有正确填充对象
- javascript - Vue - 如何制作
基于外部控制动态激活 - php - 如何在php中将上传图像到服务器从字符串更改为多部分?
- sql - 使用子查询更新表