最大总和查询不适用于弹性搜索

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 的字段,它是销售额的总和。这样做使我能够在字段上使用普通过滤器,从而提供准确的解决方案。