最大总和查询不适用于弹性搜索
Biggest sum query doesn't work for elasticsearch
我正在尝试通过 elasticsearch 查找特定时期内的最大销售额。但是,出于某种原因,我的查询没有找到最大销售额。这是我提出的查询:
GET stock/_search
{
"size": 0,
"aggs": {
"sales_per_product": {
"terms": {
"field": "offer.product.id",
"order": {
"sum_sales": "desc"
},
"size": 1
},
"aggs": {
"sum_sales": {
"sum": {
"field": "sales"
}
}
}
}
}
}
此查询在我的示例中给出以下响应:
"buckets" : [{
"key" : 241630,
"doc_count" : 67,
"sum_sales" : {
"value" : 1621.0
}
}]
但是,最大销售额实际上是 1733,这可以在以下查询示例中看到:
GET stock/_search
{
"size": 0,
"query": {
"bool": {
"filter": [
{
"term": {
"offer.product.id": "241630"
}
}
]
}
},
"aggs": {
"sales_per_product": {
"terms": {
"field": "offer.product.id",
"order": {
"sum_sales": "desc"
},
"size": 1
},
"aggs": {
"sum_sales": {
"sum": {
"field": "sales"
}
}
}
}
}
}
结果:
"buckets" : [{
"key" : 241630,
"doc_count" : 73,
"sum_sales" : {
"value" : 1733.0
}
}]
我不明白我最初的查询有什么问题。有什么我想念的吗?
我通过增加一个更大的尺寸来解决这个问题,从 1 到 100。但是没有更好的方法吗?如何保证我将来不需要使用更大的桶尺寸? (因为更大的桶大小会大大降低性能)
由于分片数大于 1,这是 elasticsearch 的正常行为。当shard个数大于1时,elasticsearch对每个shard分别进行aggs,得到总结果的前x
个,发送给master节点进行最终计算。您可以在 shard_size
部分看到它 here。这个x
默认是size*1.5+10。
这意味着当您 运行 您的 terms
aggs
大小为 10 时,每个分片 returns 25 个桶。可能在第一个分片的前 25 个结果中有 bucket,但不在第二个分片的前 25 个结果中。因此 aggs
结果并不完全准确。更准确的说,可以增加shard_size
。它肯定会对你的执行时间产生负面影响。为此,您可以将以下行添加到您的查询中:
aggs:{
"sales_per_product": {
"terms": {
"field": "offer.product.id",
"size": 1,
"shard_size": 30
}
}
}
我通过使用 pivot transform for elasticsearch 解决了这个问题。
我对产品的转换进行了分组,并有一个名为 sum_sales 的字段,它是销售额的总和。这样做使我能够在字段上使用普通过滤器,从而提供准确的解决方案。
我正在尝试通过 elasticsearch 查找特定时期内的最大销售额。但是,出于某种原因,我的查询没有找到最大销售额。这是我提出的查询:
GET stock/_search
{
"size": 0,
"aggs": {
"sales_per_product": {
"terms": {
"field": "offer.product.id",
"order": {
"sum_sales": "desc"
},
"size": 1
},
"aggs": {
"sum_sales": {
"sum": {
"field": "sales"
}
}
}
}
}
}
此查询在我的示例中给出以下响应:
"buckets" : [{
"key" : 241630,
"doc_count" : 67,
"sum_sales" : {
"value" : 1621.0
}
}]
但是,最大销售额实际上是 1733,这可以在以下查询示例中看到:
GET stock/_search
{
"size": 0,
"query": {
"bool": {
"filter": [
{
"term": {
"offer.product.id": "241630"
}
}
]
}
},
"aggs": {
"sales_per_product": {
"terms": {
"field": "offer.product.id",
"order": {
"sum_sales": "desc"
},
"size": 1
},
"aggs": {
"sum_sales": {
"sum": {
"field": "sales"
}
}
}
}
}
}
结果:
"buckets" : [{
"key" : 241630,
"doc_count" : 73,
"sum_sales" : {
"value" : 1733.0
}
}]
我不明白我最初的查询有什么问题。有什么我想念的吗?
我通过增加一个更大的尺寸来解决这个问题,从 1 到 100。但是没有更好的方法吗?如何保证我将来不需要使用更大的桶尺寸? (因为更大的桶大小会大大降低性能)
由于分片数大于 1,这是 elasticsearch 的正常行为。当shard个数大于1时,elasticsearch对每个shard分别进行aggs,得到总结果的前x
个,发送给master节点进行最终计算。您可以在 shard_size
部分看到它 here。这个x
默认是size*1.5+10。
这意味着当您 运行 您的 terms
aggs
大小为 10 时,每个分片 returns 25 个桶。可能在第一个分片的前 25 个结果中有 bucket,但不在第二个分片的前 25 个结果中。因此 aggs
结果并不完全准确。更准确的说,可以增加shard_size
。它肯定会对你的执行时间产生负面影响。为此,您可以将以下行添加到您的查询中:
aggs:{
"sales_per_product": {
"terms": {
"field": "offer.product.id",
"size": 1,
"shard_size": 30
}
}
}
我通过使用 pivot transform for elasticsearch 解决了这个问题。
我对产品的转换进行了分组,并有一个名为 sum_sales 的字段,它是销售额的总和。这样做使我能够在字段上使用普通过滤器,从而提供准确的解决方案。