2.X/2. Search in Depth

2-3-07. Cross-fields Entity Search

drscg 2017. 9. 30. 00:20

Now we come to a common pattern: cross-fields entity search. With entities like personproduct, or address, the identifying information is spread across several fields. We may have a person indexed as follows:

이제 일반적인 패턴(여러 field에 대한 항목 검색 - cross fields entity search)을 시작해 보자. 사람(person)제품(product)주소(address) 같은 항목의 식별 정보는, 여러 field에 걸쳐 저장한다. 특정인의 정보는 아래처럼 색인될 것이다.

{
    "firstname":  "Peter",
    "lastname":   "Smith"
}

Or an address like this:

또, 주소는 아래처럼 …

{
    "street":   "5 Poland Street",
    "city":     "London",
    "country":  "United Kingdom",
    "postcode": "W1V 3DG"
}

This sounds a lot like the example we described in Multiple Query Strings, but there is a big difference between these two scenarios. In Multiple Query Strings, we used a separate query string for each field. In this scenario, we want to search across multiple fields with a single query string.

이것은 Multiple Query Strings에서 언급했던 예제와 많이 비슷하나, 이 두 시나리오 사이에는 많은 차이가 있다. Multiple Query Strings에서는, 각 field마다 개별적인 query string을 사용한다. 이 시나리오에서는, 하나의 query string으로 여러 field를 검색하려 한다.

Our user might search for the person "Peter Smith" or for the address "Poland Street W1V". Each of those words appears in a different field, so using a dis_max / best_fields query to find the singlebest-matching field is clearly the wrong approach.

사용자들은 "Peter Smith" 라는 사람을 검색하거나, "Poland Street W1V" 라는 주소를 검색하려 할 것이다. 해당 단어들 각각은 다른 field에 있다. 그래서 하나의 가장 일치하는 field를 발견하기 위해, dis_maxbest fields query를 사용하는 것은, 명백히 잘못된 접근 방식이다.

A Naive Approachedit

Really, we want to query each field in turn and add up the scores of every field that matches, which sounds like a job for the bool query:

실제로, 각 field를 차례로 query하고, 일치하는 모든 field의 score를 더한다면, bool query로 하는 동작처럼 보인다.

{
  "query": {
    "bool": {
      "should": [
        { "match": { "street":    "Poland Street W1V" }},
        { "match": { "city":      "Poland Street W1V" }},
        { "match": { "country":   "Poland Street W1V" }},
        { "match": { "postcode":  "Poland Street W1V" }}
      ]
    }
  }
}

Repeating the query string for every field soon becomes tedious. We can use the multi_match query instead, and set the type to most_fields to tell it to combine the scores of all matching fields:

모든 field에 대해 query string을 반복하는 것은 좀 아니다. 대신, multi_match query를 사용하고, 일치하는 field 모두의 score를 조합하도록, type 을 most_fields 로 설정할 수 있다.

{
  "query": {
    "multi_match": {
      "query":       "Poland Street W1V",
      "type":        "most_fields",
      "fields":      [ "street", "city", "country", "postcode" ]
    }
  }
}

Problems with the most_fields Approachedit

The most_fields approach to entity search has some problems that are not immediately obvious:

항목 검색을 위한 most_fields 방식은 명확하지 않은 몇 가지 문제점을 가지고 있다.

  • It is designed to find the most fields matching any words, rather than to find the most matching words across all fields.

    모든 field에 걸쳐(across all fields), 대부분이 일치하는 단어를 찾는 것이 아니라, 특정(any) 단어와 일치하는 대부분의 field를 찾도록 설계되었다.

  • It can’t use the operator or minimum_should_match parameters to reduce the long tail of less-relevant results.

    더 적게 관련된 결과의 불필요함(long tail)을 줄이기 위해, operator 나 minium_should_match 매개변수를 사용할 수 없다.

  • Term frequencies are different in each field and could interfere with each other to produce badly ordered results.

    TF는 각 field마다 다르고, 부정확한 순서의 결과가 나오도록, 서로를 간섭할 수 있다.


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

2-3-05. multi_match Query  (0) 2017.09.30
2-3-06. Most Fields  (0) 2017.09.30
2-3-08. Field-Centric Queries  (0) 2017.09.28
2-3-09. Custom _all Fields  (0) 2017.09.28
2-3-10. cross-fields Queries  (0) 2017.09.28