2.X/2. Search in Depth

2-3-01. Multiple Query Strings

drscg 2017. 9. 30. 00:57

The simplest multifield query to deal with is the one where we can map search terms to specific fields. If we know that War and Peace is the title, and Leo Tolstoy is the author, it is easy to write each of these conditions as a match clause and to combine them with a bool query:

가장 간단한 다중 field query는, 특정 field에 검색 조건을 mapping 하는 것이다. War and Peace 가 title이고, Leo Tolstoy가 author 라는 것을 안다면, match 절에 이러한 조건을 각각 쓰고, bool query로 그것들을 조합하면 된다.

GET /_search
{
  "query": {
    "bool": {
      "should": [
        { "match": { "title":  "War and Peace" }},
        { "match": { "author": "Leo Tolstoy"   }}
      ]
    }
  }
}

The bool query takes a more-matches-is-better approach, so the score from each match clause will be added together to provide the final _score for each document. Documents that match both clauses will score higher than documents that match just one clause.

bool query는 더 많이 일치할수록 더 좋다(more-matches-is–better) 라는 접근 방식을 가진다. 그래서, 각 match 절의 score는 각 document의 최종 _score 를 제공하기 위해 모두 더해진다. 두 절 모두에 일치하는 document는, 한 절만 일치하는 document보다, 더 높은 score를 가지게 된다.

Of course, you’re not restricted to using just match clauses: the bool query can wrap any other query type, including other bool queries. We could add a clause to specify that we prefer to see versions of the book that have been translated by specific translators:

물론, 단순히 match 절을 사용하는 것에는 제한이 없다. bool query는 다른 bool query를 포함한 다른 query 형태를 감쌀 수 있다. 특정 translator에 의해 번역된 책을 선호하도록 지정하는 절을 추가할 수 있다.

GET /_search
{
  "query": {
    "bool": {
      "should": [
        { "match": { "title":  "War and Peace" }},
        { "match": { "author": "Leo Tolstoy"   }},
        { "bool":  {
          "should": [
            { "match": { "translator": "Constance Garnett" }},
            { "match": { "translator": "Louise Maude"      }}
          ]
        }}
      ]
    }
  }
}

Why did we put the translator clauses inside a separate bool query? All four match queries are should clauses, so why didn’t we just put the translator clauses at the same level as the title and author clauses?

개별 bool query 안에 translator 절을 둔 이유는 무엇일까? 모두 4개의 match 절은 should 절이다. 그런데 왜 translator 절을 title이나 author 절과 동일한 단계에 두지 않았을까?

The answer lies in how the score is calculated. The bool query runs each match query, adds their scores together, then multiplies by the number of matching clauses, and divides by the total number of clauses. Each clause at the same level has the same weight. In the preceding query, the boolquery containing the translator clauses counts for one-third of the total score. If we had put the translator clauses at the same level as title and author, they would have reduced the contribution of the title and author clauses to one-quarter each.

정답은 score가 계산되는 방법에 있다. bool query는 각 match query를 실행하고, 그들의 score를 모두 더한다. 그 다음에 일치하는 절의 수로 곱한다. 그리고 절의 총 수로 나눈다. 동일한 단계에 있는 각 절은 동일한 비중을 가진다. 위의 query에서, translator 절을 포함하고 있는 bool query는, 총 score의 1/3을 차지한다. 만약 translator 절을 title이나 author 절과 동일한 단계로 둔다면, title이나 author 절이 차지하는 비중이 각각 1/4로 줄어든다.

Prioritizing Clausesedit

It is likely that an even one-third split between clauses is not what we need for the preceding query.Probably we’re more interested in the title and author clauses than we are in the translator clauses. We need to tune the query to make the title and author clauses relatively more important.

절(clause)의 비중을 1/3로 나누는 것조차도, 위의 query에서 적당하지 않을 수 있다. 아마도 title 이나 author 절에 더 많은 관심을 가지고 있고, 그 다음이 translator 절일 것이다. title 이나 author 절이 상대적으로 더 중요하게 되도록, query를 조정해야 한다.

The simplest weapon in our tuning arsenal is the boost parameter. To increase the weight of the title and author fields, give them a boost value higher than 1:

조정 방법 중 가장 간단한 수단은 boost 매개변수다. title 이나 author field의 비중을 증가시키기 위해, 1 보다 큰 boost 값을 적용한다.

GET /_search
{
  "query": {
    "bool": {
      "should": [
        { "match": { 
            "title":  {
              "query": "War and Peace",
              "boost": 2
        }}},
        { "match": { 
            "author":  {
              "query": "Leo Tolstoy",
              "boost": 2
        }}},
        { "bool":  { 
            "should": [
              { "match": { "translator": "Constance Garnett" }},
              { "match": { "translator": "Louise Maude"      }}
            ]
        }}
      ]
    }
  }
}

 

title 이나 author 절은 boost 값 2 를 가지고 있다.

bool 절의 내부는 기본 boost 1 을 가진다.

The "best" value for the boost parameter is most easily determined by trial and error: set a boostvalue, run test queries, repeat. A reasonable range for boost lies between 1 and 10, maybe 15. Boosts higher than that have little more impact because scores are normalized.

boost 매개변수에 대한 "최선" 의 값은 시행착오(boost 값 지정, query 테스트 실행, 반복)에 의해, 가장 쉽게 결정된다. boost 의 합리적인 범위는 1 ~ 10 또는 15 이다. 가중치가 이것보다 높으면, 거의 영향을 미치지 않는다. 왜냐하면 score는 정규화되기 때문이다.


'2.X > 2. Search in Depth' 카테고리의 다른 글

2-2-8. Relevance Is Broken!  (0) 2017.09.30
2-3. Multifield Search  (0) 2017.09.30
2-3-02. Single Query String  (0) 2017.09.30
2-3-03. Best Fields  (0) 2017.09.30
2-3-04. Tuning Best Fields Queries  (0) 2017.09.30