個人的に長い間望んでいた件の機能を実現するtop_hits aggregation、これが追加されたバージョン1.3.0がついにリリースされました。
The top hits aggregation (#6124) resolves the most +1′ed issue in the history of Elasticsearch: Field collapsing/combining. You can now bucket on a common field like brand_name, and get the best matching documents for each bucket. Even highlighting is supported!
Solrでは元からあった機能なのですが、Elasitcsearchにはなくて、以下のIssueが「14 Jul 2010」からずっとOpenな状態で多々議論がされていました。
Field Collapsing/Combining #256
https://github.com/elasticsearch/elasticsearch/issues/256
それに関して動きがあったのは5月の以下のIssue。
(もっと前からだろうけど、気づいたのはその頃)
Aggregations: Add top_hits aggregation #6124
https://github.com/elasticsearch/elasticsearch/pull/6124
確認すると、確かに期待してる機能なようなので以下のドキュメントを参考にtop_hits aggregation
を使ったクエリを書いてみました。
field collapse example
http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-aggregations-metrics-top-hits-aggregation.html#_field_collapse_example
{
"size": 0,
"query": {
"match": {
"title": "ほげ"
}
},
"aggs": {
"hits": {
"terms": {
"field": "gid",
"order": {
"top_hit": "desc"
}
},
"aggs": {
"top": {
"top_hits": {
"sort": [
{
"released_at": {
"order": "desc"
}
}
],
"from": 0,
"size": 1
}
},
"top_hit": {
"max": {
"field": "download_count"
}
}
}
},
"stats": {
"cardinality": {
"field": "gid"
}
},
}
}
この例だとtitle
にほげ
を含むドキュメントに関して、gid
でグルーピングし、各グループ内ではreleased_at
が直近の1件を取得して、download_count
が大きい順に並んで返ってきてるっぽい(hits
)。
ちなみに、stats
の方ではcardinality aggregation
を使って、gid
でグルーピングされた後の件数を取得してます。
cardinality aggregation
に関しては、まだexperimental!
らしい...。
http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-aggregations-metrics-cardinality-aggregation.html
ちなみにtop_hits aggregation
というかterms aggregation
について分からないことがあってツイートしてたら、Elasticsearchの中の人(johtaniさん)がキャッチアップしてくれて、相談にのってくれました。
ありがたや〜。
https://gist.github.com/shoito/7bd8800d40d3a5b3da13
まだまだ検証しないといけないことは多々あるので、時間を作ってちまちま進めていこうと思います。