2.X/1. Getting Started

1-08-1. Sorting

drscg 2017. 9. 30. 18:15

In order to sort by relevance, we need to represent relevance as a value. In Elasticsearch, the relevance score is represented by the floating-point number returned in the search results as the _scoreso the default sort order is _score descending.

relevance로 정렬하기 위해, relevance를 값으로 표시해야 한다. Elasticsearch에서 relevance score 는 _score 로, 검색 결과에 반환되는, 부동 소수점 숫자로 표시된다. 기본 정렬 순서는 _score 의 내림차순이다.

Sometimes, though, you don’t have a meaningful relevance score. For instance, the following query just returns all tweets whose user_id field has the value 1:

그러나, 가끔 의미 있는 relevance score를 가지지 않을 수도 있다. 예를 들면, 아래 query는 user_id field의 값이 1 인 모든 tweet을 반환한다.

GET /_search
{
    "query" : {
        "bool" : {
            "filter" : {
                "term" : {
                    "user_id" : 1
                }
            }
        }
    }
}

There isn’t a meaningful score here: because we are using a filter, we are indicating that we just want the documents that match user_id: 1 with no attempt to determine relevance. Documents will be returned in effectively random order, and each document will have a score of zero.

여기에서 score는 의미가 없다. filter를 사용하고 있기 때문에, relevance를 정하지 않고, user_id: 1 에 일치하는 document만을 나타낸다. document는 무작위로 효과적으로 반환된다. 그리고, 각 document의 score는 0 이다

Note

If a score of zero makes your life difficult for logistical reasons, you can use a constant_score query instead:

score가 zero인 것으로 인해 로직상에 어려움이 있다면, 대신 constant_score query를 사용할 수 있다.

GET /_search
{
    "query" : {
        "constant_score" : {
            "filter" : {
                "term" : {
                    "user_id" : 1
                }
            }
        }
    }
}

This will apply a constant score (default of 1) to all documents. It will perform the same as the above query, and all documents will be returned randomly like before, they’ll just have a score of one instead of zero.

이것은 모든 document에 일정한 score(기본값 1)를 적용한다. 위의 query처럼 동일하게 동작하고, 이전과 마찬가지로 무작위로 반환된다. zero 대신 score 1 을 가질 뿐이다.

Sorting by Field Valuesedit

In this case, it probably makes sense to sort tweets by recency, with the most recent tweets first. We can do this with the sort parameter:

이 경우에는, 아마 가장 최근의 tweet이 우선하도록, 정렬하는 것이 맞을 것이다. 이는 sort 매개변수로 가능하다.

GET /_search
{
    "query" : {
        "bool" : {
            "filter" : { "term" : { "user_id" : 1 }}
        }
    },
    "sort": { "date": { "order": "desc" }}
}

You will notice two differences in the results:

결과에서 두 가지 차이점을 발견할 수 있다.

"hits" : {
    "total" :           6,
    "max_score" :       null, 
    "hits" : [ {
        "_index" :      "us",
        "_type" :       "tweet",
        "_id" :         "14",
        "_score" :      null, 
        "_source" :     {
             "date":    "2014-09-24",
             ...
        },
        "sort" :        [ 1411516800000 ] 
    },
    ...
}

 

정렬에 사용되지 않았기 때문에 _score 는 계산되지 않는다.

epoch time을 millisecond로 표시한, date field의 값이 sort 값으로 반환된다.

The first is that we have a new element in each result called sort, which contains the value(s) that was used for sorting. In this case, we sorted on date, which internally is indexed as milliseconds since the epoch. The long number 1411516800000 is equivalent to the date string 2014-09-24 00:00:00 UTC.

각 결과에서 볼 수 있는 새로운 요소 중, 첫 번째는 정렬에 사용되는 값을 포함하고 있는 sort 이다. 이 경우에, 내부적으로 epoch time을 millisecond로 바꾸어(milliseconds since the epoch) 색인된, date 로 정렬하였다. long number 1411516800000 는 date string 2014-09-24 00:00:00 UTC 와 동일한 값이다.

The second is that the _score and max_score are both nullCalculating the _score can be quite expensive, and usually its only purpose is for sorting; we’re not sorting by relevance, so it doesn’t make sense to keep track of the _score. If you want the _score to be calculated regardless, you can set the track_scores parameter to true.

두 번째는, _score 와 max_score 가 모두 null 이라는 점이다. _score 를 계산한다는 것은 꽤 비용이 발생하는 작업이고, 일반적으로 그것의 유일한 목적은 정렬이다. 지금은 relevance로 정렬하지 않았고, 따라서 _score 를 파악하는 것은 의미가 없다. 그럼에도 불구하고, _score 가 계산되기를 원한다면, track_scores매개변수를 true 로 설정하면 된다.

Tip

As a shortcut, you can specify just the name of the field to sort on:

정렬할 field의 이름만 지정할 수 있다.

    "sort": "number_of_children"

Fields will be sorted in ascending order by default, and the _score value in descending order.

field는 기본적으로 오름차순으로 정렬된다. 그리고 _score 는 내림차순이다.

Multilevel Sortingedit

Perhaps we want to combine the _score from a query with the date, and show all matching results sorted first by date, then by relevance:

date 를 가진 query에서, _score 를 조합하려 할 수도 있다. 그리고, 모든 일치하는 결과를 date로 먼저 정렬하고, 그 다음에 relevance로 정렬하기를 원할 수 있다.

GET /_search
{
    "query" : {
        "bool" : {
            "must":   { "match": { "tweet": "manage text search" }},
            "filter" : { "term" : { "user_id" : 2 }}
        }
    },
    "sort": [
        { "date":   { "order": "desc" }},
        { "_score": { "order": "desc" }}
    ]
}

Order is important. Results are sorted by the first criterion first. Only results whose first sort value is identical will then be sorted by the second criterion, and so on.

순서가 중요하다. 결과는 첫 번째 기준에 의해 먼저 정렬된다. 첫 번째 정렬(sort) 값의 결과가 동일하면, 결과는 두 번째 기준에 의해 정렬된다.

Multilevel sorting doesn’t have to involve the _score. You could sort by using several different fields,on geo-distance or on a custom value calculated in a script.

다단계 정렬이 반드시 _score 를 포함해야 하는 것은 아니다. 지리적 거리나 script에 의해 계산된 사용자 정의 값으로, 여러 가지 다른 field를 사용해 정렬할 수 있다.

Note

Query-string search also supports custom sorting, using the sort parameter in the query string:

query-string 검색 또한, query string에서 sort 매개변수를 사용하여, 사용자 정의 정렬을 지원한다.

GET /_search?sort=date:desc&sort=_score&q=search

Sorting on Multivalue Fieldsedit

When sorting on fields with more than one value, remember that the values do not have any intrinsic order; a multivalue field is just a bag of values. Which one do you choose to sort on?

하나 이상의 값을 가진 field를 정렬하는 경우, 값들은 어떤 고유한 순서도 가지고 있지 않다는 점을 기억하자. 다중 값 field는 단지 값의 주머니일 뿐이다. 정렬하기 위해 어떤 것을 선택해야 할까?

For numbers and dates, you can reduce a multivalue field to a single value by using the minmaxavg, or sum sort modesFor instance, you could sort on the earliest date in each dates field by using the following:

number나 date의 경우, 다중 값 field를, minmaxavg 또는 sum _sort mode_를 사용하여, 하나의 값으로 줄일 수 있다. 예를 들면, 각 dates field에 있는 가장 빠른 날짜로 정렬할 수 있다.

"sort": {
    "dates": {
        "order": "asc",
        "mode":  "min"
    }
}


'2.X > 1. Getting Started' 카테고리의 다른 글

1-07-6. Validating Queries  (0) 2017.09.30
1-08. Sorting and Relevance  (0) 2017.09.30
1-08-2. String Sorting and Multifields  (0) 2017.09.30
1-08-3. What Is Relevance?  (0) 2017.09.30
1-08-4. Doc Values Intro  (0) 2017.09.30