A common requirement is the need to present search results grouped by a particular field. We might want to return the most relevant blog posts grouped by the user’s name. Grouping by name implies the need for a terms
aggregation. To be able to group on the user’s whole name, the name field should be available in its original not_analyzed
form, as explained in Aggregations and Analysis:
특정 field로 그룹화된 검색 결과를 제시하는 것은 일반적인 요구 사항이다. 사용자의 이름으로 그룹화된 가장 관련 있는 블로그 게시물을 검색해 보자. 이름으로 그룹화하는 것은 terms
aggregation이 필요하다는 의미이다. 사용자의 전체 이름으로 그룹화하려면, Aggregations and Analysis에서 설명하였듯이, name field는 원래의 not_analyzed
형태로 사용할 수 있어야 한다.
PUT /my_index/_mapping/blogpost { "properties": { "user": { "properties": { "name": { "type": "string", "fields": { "raw": { "type": "string", "index": "not_analyzed" } } } } } } }
Then add some data:
그 다음에, 데이터를 추가한다.
PUT /my_index/user/1 { "name": "John Smith", "email": "john@smith.com", "dob": "1970/10/24" } PUT /my_index/blogpost/2 { "title": "Relationships", "body": "It's complicated...", "user": { "id": 1, "name": "John Smith" } } PUT /my_index/user/3 { "name": "Alice John", "email": "alice@john.com", "dob": "1979/01/04" } PUT /my_index/blogpost/4 { "title": "Relationships are cool", "body": "It's not complicated at all...", "user": { "id": 3, "name": "Alice John" } }
Now we can run a query looking for blog posts about relationships
, by users called John
, and group the results by user, thanks to the top_hits
aggregation:
이제 John
이라는 사용자의, relationships
블로그 게시물을 검색하기 위해, query를 실행할 수 있다. 그리고, top_hits
aggregation를 이용해, 결과를 사용자별로 그룹화할 수 있다.
GET /my_index/blogpost/_search { "size" : 0, "query": { "bool": { "must": [ { "match": { "title": "relationships" }}, { "match": { "user.name": "John" }} ] } }, "aggs": { "users": { "terms": { "field": "user.name.raw", "order": { "top_score": "desc" } }, "aggs": { "top_score": { "max": { "script": "_score" }}, "blogposts": { "top_hits": { "_source": "title", "size": 5 }} } } } }
| |
| |
| |
| |
|
The abbreviated response is shown here:
response는 다음과 같다.
... "hits": { "total": 2, "max_score": 0, "hits": [] }, "aggregations": { "users": { "buckets": [ { "key": "John Smith", "doc_count": 1, "blogposts": { "hits": { "total": 1, "max_score": 0.35258877, "hits": [ { "_index": "my_index", "_type": "blogpost", "_id": "2", "_score": 0.35258877, "_source": { "title": "Relationships" } } ] } }, "top_score": { "value": 0.3525887727737427 } }, ...
| |
상위 결과에 나타나는 각 user에 대한 bucket이 있다. | |
각 user의 bucket 아래에, 해당 사용자에 대한 상위 결과를 포함하는 | |
user bucket은 사용자의 가장 관련 있는 블로그 게시물에 의해 정렬된다. |
Using the top_hits
aggregation is the equivalent of running a query to return the names of the users with the most relevant blog posts, and then running the same query for each user, to get their best blog posts. But it is much more efficient.
top_hits
aggregation의 사용은 가장 관련 있는 블로그 게시물을 가진 사용자의 이름을 반환하는, query를 실행하고, 그 다음에 해당 사용자 최고의 블로그 게시물을 얻기 위해, 각각의 사용자에 대한 동일한 query를 실행하는 것과 동일하다. 하지만 이것이 훨씬 더 효율적이다.
The top hits returned in each bucket are the result of running a light mini-query based on the original main query. The mini-query supports the usual features that you would expect from search such as highlighting and pagination.
각 bucket에서 반환되는 상위 hits는 원래의 주 query를 기반으로 한, 가벼운 mini-query 의 결과이다. mini-query는 하이라이트와 페이지 계산(pagination)처럼, 검색에서 기대할 수 있는 일반적인 기능을 지원한다.
'2.X > 6. Modeling Your Data' 카테고리의 다른 글
6-1-1. Application-side Joins (0) | 2017.09.23 |
---|---|
6-1-2. Denormalizing Your Data (0) | 2017.09.23 |
6-1-4. Denormalization and Concurrency (0) | 2017.09.23 |
6-1-5. Solving Concurrency Issues (0) | 2017.09.23 |
6-2. Nested Objects (0) | 2017.09.23 |