首页 > 解决方案 > 从弹性搜索中获取最后 2 个条目的平均值

问题描述

我正在尝试从弹性搜索中获取最后 2 个条目的平均值,但被困在了这里。以下是我在弹性搜索中的数据:

{
    "took": 115,
    "timed_out": false,
    "_shards": {
        "total": 5,
        "successful": 5,
        "failed": 0
    },
    "hits": {
        "total": 22696195,
        "max_score": 1.0,
        "hits": [{
                "_index": "queue_pings",
                "_type": "QueuePings",
                "_id": "AWGtuVzycUtYPYuAwOzr",
                "_score": 1.0,
                "_source": {
                    "queue": "queue1",
                    "length": 134,
                    "timestamp": "2018-02-19 11:01:01"
                }
            }, {
                "_index": "queue_pings",
                "_type": "QueuePings",
                "_id": "AWGtuV0DcUtYPYuAwOzs",
                "_score": 1.0,
                "_source": {
                    "queue": "queue2",
                    "length": 1202,
                    "timestamp": "2018-02-19 11:01:01"
                }
            }, {
                "_index": "queue_pings",
                "_type": "QueuePings",
                "_id": "AWGtuV0dWFpRPa9T9mcf",
                "_score": 1.0,
                "_source": {
                    "queue": "queue1",
                    "length": 120,
                    "timestamp": "2018-02-19 11:00:01"
                }
            }, {
                "_index": "queue_pings",
                "_type": "QueuePings",
                "_id": "AWGtuV0wTPjiqgqsDMAM",
                "_score": 1.0,
                "_source": {
                    "queue": "queue2",
                    "length": 1762,
                    "timestamp": "2018-02-19 11:00:01"
                }
            }, {
                "_index": "queue_pings",
                "_type": "QueuePings",
                "_id": "AWGtuV09WFpRPa9T9mcg",
                "_score": 1.0,
                "_source": {
                    "queue": "queue3",
                    "length": 220,
                    "timestamp": "2018-02-19 11:00:01"
                }
            }
        ]
    }
}

我想获得最后 2 个条目的平均值,其中queue = queue1.

这是等效的MYSQL查询SELECT AVG(length) FROM queue_pings WHERE queue = 'queue1' order by timestamp desc limit 2;

到目前为止我已经尝试过:

GET /queue_pings/_search?size=2
{
  "aggs": {
    "queue_filter" : {
      "filter" : { "term" : { "queue" : "queue1" } },
      "aggs" : {
        "queue_avg" : { "avg" : { "field" : "length" } }
      }
    }
  }
}

编辑:添加映射

{
  "queue_pings": {
    "mappings": {
      "QueuePings": {
        "properties": {
          "length": {
            "type": "long"
          },
          "queue": {
            "type": "keyword"
          },
          "timestamp": {
            "type": "date",
            "ignore_malformed": true,
            "format": "yyyy-MM-dd HH:mm:ss"
          }
        }
      }
    }
  }
}

标签: elasticsearch

解决方案


您不能在 Elasticsearch 的查询中执行此操作。这个想法有点像一个两步过程: - 首先获取最大日期(最新的日期),如果您愿意,可以像 MAX 聚合一样 - 然后让前两个文档“小于”这个最新日期,这基本上是一个top_hits聚合

而且您不能对 a 的结果应用聚合(AVG)top_hits。如果您将结果限制为 2 然后取平均值,您也不能这样做,因为它会匹配更多文档,对它们进行 AVG 然后只给您两个。

无论如何,在我看来,最简单的解决方案是

{
   "size": 2,
   "sort":[
      {
         "timestamp":{
            "order":"desc"
         }
      }
   ],
   "query":{
        "term":{
            "queue.keyword":"queue1"
        }
    }
}

然后在你得到两个结果后自己计算平均值。这是您可以在 Elasticsearch 之外执行的简单操作。


推荐阅读