如何在top_hits上聚合弹性搜索结果

时间:2016-04-01 06:56:55

标签: elasticsearch

以下是示例文档:

{
    "player": "Jim",
    "score" : 5
    "timestamp": 1459492890000
}

{
    "player": "Jim",
    "score" : 7
    "timestamp": 1459492895000
}

{
    "player": "Dave",
    "score" : 9
    "timestamp": 1459492894000
}

{
    "player": "Dave",
    "score" : 4
    "timestamp": 1459492898000
}

我希望获得每位玩家的最新分数,然后获得所有这些分数的平均值。所以答案是5.5。吉姆的最新得分是7,戴夫的最新得分是4.这两者之间的平均值是5.5

我发现获取播放器“最新”文档的唯一方法是使用top_hits聚合。但是,在我收到最新文档后,我似乎无法再进行其他聚合。

这是我提出的最好的:

{
  "aggs": {
    "last_score": {
      "terms": { "field": "player" },
      "aggs": {
        "last_score_hits": {
          "top_hits": {
            "sort": [ { "timestamp": { "order": "desc" } } ],
            "size": 1
          },
          "aggs": {
            "avg_score": {
              "avg": { "field": "score" }
            }
          }
        }
      }
    }
  }
}

然而,这给了我这个错误:

  

[top_hits]类型的聚合器[last_score_hits]无法接受   子聚合

如果还有其他方法可以在不使用top_hits的情况下完成此搜索,那么我会全力以赴。

2 个答案:

答案 0 :(得分:0)

您尝试将avg_score作为last_score_hits的子聚合。 要获得成功,您必须将avg_score作为last_score的子聚合。请参阅下面的示例:

{
  "aggs": {
    "last_score": {
      "terms": {
        "field": "player"
      },
      "aggs": {
        "last_score_hits": {
          "top_hits": {
            "sort": [
              {
                "timestamp": {
                  "order": "desc"
                }
              }
            ],
            "size": 1
          }
        },
        "avg_score": {
          "avg": {
            "field": "score"
          }
        }
      }
    }
  }
}

答案 1 :(得分:0)

您可以在top_hit的并行级别上进行其他聚合,但不能在top_hit以下进行任何sub_aggregation。 ElasticSearch不支持它。 here is the link to Github issue

您可以进行并行级别的聚合,例如:

"aggs": {
    "top_hits_agg": {
        "top_hits": {
            "size": 10,
            "_source": {
              "includes": ["score"]
            }
        }
    },
    "avg_agg": {
        "avg": {
            "field": "score"
        }
    }
}