是否有可能使弹性搜索返回基于不同文档字段的聚合键?
我们将外部id和外部名称都放置在类型中,然后对id进行聚合,但希望获得返回的名称。名称不是唯一的,因此不适合对它们进行聚合。我知道它们在记录集中也不一定是唯一的,但是可以接受从记录集中的单个记录中采样的名称。
例如,假设我们的数据是关于产品的销售。每个销售都有与之关联的产品id和产品名称。
// Sales
{ "product_id": 1, "product_name": "Beer", "quantity": 3, … }
{ "product_id": 1, "product_name": "Beer", "quantity": 2, … }
{ "product_id": 2, "product_name": "Wine", "quantity": 6, … }
查询:"aggregations": {
"product": {
"terms": {
"field": "product_id"
},
"aggregations": {
"day": {
"count": {
"value_count": {
"field": "quantity"
}
}
}
}
}
}
}
结果:…
"aggregations": {
"product": {
"buckets": [
{
"key": "1",
"doc_count": 2,
"count": {
"value": 5
}
},{
"key": "2",
"doc_count": 1,
"count": {
"value": 6
}
]
}
}
…
想要的结果:
…
"aggregations": {
"product": {
"buckets": [
{
"key": "Beer",
"doc_count": 2,
"count": {
"value": 5
}
},{
"key": "Wine",
"doc_count": 1,
"count": {
"value": 6
}
]
}
}
…
在阅读了关于脚本的文档后,我认为这是不可能的,因为它只对值进行评估,并且似乎无法访问整个文档(因为没有文档,而是一组文档)。
如果您只使用script属性,则可以使用脚本来完成此操作(然后该属性可以访问整个文档)。然后在你的客户端中拆分:例如
"aggs": {
"types_of": {
"terms": {
"script": "doc['product_name'].value + '|' + doc['product_id'].value"
}
}
}
如果您对索引过程拥有全部权力,我建议您根据product_id自行添加一个新字段(不进行分析),并在该字段上进行聚合。
我认为(但我可能错了)你想做的事是不可能的。
您可以使用子聚合来获取名称,因此您的查询将类似于:
"aggregations": {
"product": {
"terms": {
"field": "product_id"
},
"aggregations": {
"name": {
"terms": {
"field": "product_name"
}
},
"day": {
"count": {
"value_count": {
"field": "quantity"
}
}
}
}
}
}
}
根据我的理解,问题希望返回product_name
以及product_id
的聚合结果。
这个问题可以通过topHit子聚合来解决:
{
"aggregations": {
"product": {
"terms": {
"field": "product_id"
},
"aggregations": {
"day": {
"count": {
"value_count": {
"field": "quantity"
}
}
},
"topHits": {
"top_hits": {
"from": 0,
"size": 1,
"_source": false,
"docvalue_fields": [
{
"field": "product_name"
}
]
}
}
}
}
}
}
则结果如下(删除不必要的字段):
{
"aggregations": {
"product": {
"buckets": [
{
"key": "1",
"doc_count": 2,
"topHits": {
"hits": {
"total": {
"value": 2,
"relation": "eq"
},
"hits": [
{
"fields": {
"product_name": [
"Beer"
]
}
}
]
}
},
"count": {
"value": 5
}
}
]
}
}
}
注意count
&product_name
在同一桶中。通过这种方式,我们可以将product_name
与count
连接起来。
注意:如果对product_name
进行分析/规范化,则返回的结果也将规范化。为了避免这种情况,我们可以创建一个子字段,并将该字段规范化。