2.X/1. Getting Started

1-07-5. Combining queries together

drscg 2017. 9. 30. 19:56

Real world search requests are never simple; they search multiple fields with various input text, and filter based on an array of criteria. To build sophisticated search, you will need a way to combine multiple queries together into a single search request.

현실에서 검색 request는 결코 간단하지 않다. 다양한 입력 문자열과 여러 조건의 배열을 기반으로 한 filter를 가지고 다수의 field를 검색한다. 정교한 검색을 위해, 하나의 검색 request에 다수의 query를 함께 조합해야 한다.

To do that, you can use the bool query. This query combines multiple queries together in user-defined boolean combinations. This query accepts the following parameters:

이렇게 하기 위해, bool query를 사용할 수 있다. 이 query는 사용자가 정의한 boolean 조합에서 다수의 query를 함께 조합한다. 이 query는 다음과 같늠 매개변수를 가질 수 있다.

must

Clauses that must match for the document to be included.

포함되려면 document에 반드시 일치해야 하는 절

must_not

Clauses that must not match for the document to be included.

포함되려면 document에 반드시 일치하지 않아야 하는 절

should

If these clauses match, they increase the _score; otherwise, they have no effect. They are simply used to refine the relevance score for each document.

만약 이 절이 일치하면 _score 가 증가하고, 그렇지 않으면 아무런 효과가 없다. 단순히 각 document의 relevance score를 개선하는데 사용된다.

filter

Clauses that must match, but are run in non-scoring, filtering mode. These clauses do not contribute to the score, instead they simply include/exclude documents based on their criteria.

반드시 일치하지만 score 계산이 수행되지 않는 filtering 모드. 이 절은 score와 무관하다. 대신 해당 조건을 기반으로, 단순히 document를 포함/배제한다.

Because this is the first query we’ve seen that contains other queries, we need to talk about how scores are combined. Each sub-query clause will individually calculate a relevance score for the document. Once these scores are calculated, the bool query will merge the scores together and return a single score representing the total score of the boolean operation.

이것은 우리가 본 것중 다른 query를 포함하는 첫번째 query이기 때문에, score가 조합되는 방법에 대래 이야기해 보자. 각 하부 query 절은 개별적으로 document에 대해 relevance score를 계산한다. 이들 score가 계산되면, bool query는 score를 함께 통합하고, boolean 연산의 종합 score를 나타내는 단일 score를 돌려준다.

The following query finds documents whose title field matches the query string how to make millions and that are not marked as spam. If any documents are starred or are from 2014 onward, they will rank higher than they would have otherwise. Documents that match both conditions will rank even higher:

다음 query는 title field가 query string how to make millions 에 일치해야 하고, spam 으로 표시되지 않은 document를 검색한다. 만약, document가 starred 로 tag 되거나 2014년 이후라면, 그렇지 않은 document보다 더 높은 순위를 받을 것이다. 두 조건에 모두 일치하는 document는 더 높을 것이다.

{
    "bool": {
        "must":     { "match": { "title": "how to make millions" }},
        "must_not": { "match": { "tag":   "spam" }},
        "should": [
            { "match": { "tag": "starred" }},
            { "range": { "date": { "gte": "2014-01-01" }}}
        ]
    }
}
Tip

If there are no must clauses, at least one should clause has to match. However, if there is at least one must clause, no should clauses are required to match.

must 절이 없다면 최소한 하나 이상의 should 절이 일치해야 한다. 그러나 최소한 하나 이상의 must 절이 일치한다면, should 절은 일치하지 않아도 된다.

Adding a filtering queryedit

If we don’t want the date of the document to affect scoring at all, we can re-arrange the previous example to use a filter clause:

document의 date가 score에 영향을 미치지 않게 하려면, 이전의 예제를 filter 절을 사용하도록 다시 배치할 수 있다.

{
    "bool": {
        "must":     { "match": { "title": "how to make millions" }},
        "must_not": { "match": { "tag":   "spam" }},
        "should": [
            { "match": { "tag": "starred" }}
        ],
        "filter": {
          "range": { "date": { "gte": "2014-01-01" }} 
        }
    }
}

range query가 should 절 외부의 filter 절로 이동되었다.

By moving the range query into the filter clause, we have converted it into a non-scoring query. It will no longer contribute a score to the document’s relevance ranking. And because it is now a non-scoring query, it can use the variety of optimizations available to filters which should increase performance.

range query를 filter 절로 옮김으로써, 그것은 non-scoring query로 변경되었다. 더 이상 document의 relevance score에 기여하지 않는다. 그리고 non-scoring query이기 때문에, 성능을 증가시키려는 filter에 이용할 수 있는 다영한 최적화를 사용할 수 있다.

Any query can be used in this manner. Simply move a query into the filter clause of a bool query and it automatically converts to a non-scoring filter.

모든 query가 이런 방식으로 사용될 수 있다. 단순히 query를 bool query의 filter 절로 옮기면, 자동으로 non-scoring filter로 변경된다.

If you need to filter on many different criteria, the bool query itself can be used as a non-scoring query. Simply place it inside the filter clause and continue building your boolean logic:

다른 많은 조건으로 filtering해야 한다면, bool query 자체가 non-scoring query로 사용될 수 있다. 단순히 그것을 filter 절 안에 두고, boolean 로직을 만들어 가면 된다.

{
    "bool": {
        "must":     { "match": { "title": "how to make millions" }},
        "must_not": { "match": { "tag":   "spam" }},
        "should": [
            { "match": { "tag": "starred" }}
        ],
        "filter": {
          "bool": { 
              "must": [
                  { "range": { "date": { "gte": "2014-01-01" }}},
                  { "range": { "price": { "lte": 29.99 }}}
              ],
              "must_not": [
                  { "term": { "category": "ebooks" }}
              ]
          }
        }
    }
}

filter 절에 bool query를 포함함으로써, filtering 조건에 boolean 로직을 추가할 수 있다.

By mixing and matching where Boolean queries are placed, we can flexibly encode both scoring and filtering logic in our search request.

boolean query의 위치를 섞고 일치시킴으로써, 검색 request에 score 계산과 filtering logic을 유연하게 표현할 수 있다.

constant_score Queryedit

Although not used nearly as often as the bool query, the constant_score query is still useful to have in your toolbox. The query applies a static, constant score to all matching documents. It is predominantly used when you want to execute a filter and nothing else (e.g. no scoring queries).

bool query 만큼 자주 사용되지는 않지만, constant_score query는 여전히 유용하다. query는 모든 일치하는 document에 정적으로 일정한 score를 적용한다. 대개 filter만을 실행(예: score를 계산하지 않는 query)할 때 사용된다.

You can use this instead of a bool that only has filter clauses. Performance will be identical, but it may aid in query simplicity/clarity.

filter 절만을 가진 bool 절 대신에 이것을 사용할 수 있다. 성능은 동일하나 query의 단순함/명확함에 도움이 된다.

{
    "constant_score":   {
        "filter": {
            "term": { "category": "ebooks" } 
        }
    }
}

term query는 constant_score 내부에 있어, no


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

1-07-3. Queries and Filters  (0) 2017.09.30
1-07-4. Most Important Queries  (0) 2017.09.30
1-07-6. Validating Queries  (0) 2017.09.30
1-08. Sorting and Relevance  (0) 2017.09.30
1-08-1. Sorting  (0) 2017.09.30