如何基于聚合输出值在Elasticsearch中获取文档?

时间:2019-05-17 18:01:33

标签: elasticsearch nosql aggregation querydsl elasticsearch-java-api

我想将聚合输出用作一个查询中文档过滤的输入。

例如,我想获取过去24小时内的销售单据,其中销售金额大于当月前最近3个月的平均销售金额(例如2月至4月,如果我们在5月)。平均销售额将是一个汇总。

尝试使用脚本字段,因为它会过滤文档,但不确定如何从脚本访问聚合结果。 https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-script-fields.html

另一种想法是在顶部使用3个月的日期范围查询,然后使用24小时的日期直方图,并在其下方嵌套顶部匹配项。但是,我需要某种脚本化的过滤器来基于平均销售汇总过滤掉文档。

您可以通过POST将以下内容导入到Bulk API的示例销售凭证:

{"index":{}}
{"id": 1, "date": "2019-02-01", "amount": 1000}
{"index":{}}
{"id": 2, "date": "2019-03-01", "amount": 2000}
{"index":{}}
{"id": 3, "date": "2019-04-01", "amount": 3000}
{"index":{}}
{"id": 4, "date": "2019-05-17", "amount": 1500}
{"index":{}}
{"id": 5, "date": "2019-05-17", "amount": 4000}
{"index":{}}
{"id": 6, "date": "2019-05-17", "amount": 8000}

根据上述文件,该月(5月)之前最近3M的平均值为(1000 + 2000 + 3000)/ 3 =2000。最近24小时内金额大于2000的文件仅为id 5,id 6。

在SQL中,查询看起来像

SELECT * 
FROM   sales 
WHERE  `date` >= '2019-05-17' 
       AND amount > (SELECT AVG(amount) 
                     FROM   sales 
                     WHERE  `date` BETWEEN '2019-02-01' AND '2019-04-30'); 

然后返回

id  date    amount
5   2019-05-17  4000
6   2019-05-17  8000

如何在一个查询/请求中使用Elasticsearch达到相同的目的?

1 个答案:

答案 0 :(得分:0)

Elastic团队成员Mark Walkom认为:

  

您现在不能后悔!   您将需要运行agg以获取平均值,然后运行单独的查询以获取与值匹配的文档。

https://discuss.elastic.co/t/how-to-get-documents-in-elasticsearch-based-on-aggregation-output-values/182109/2