All three of the preceding problems stem from most_fields
being field-centric rather than term-centric: it looks for the most matching fields, when really what we’re interested in is the most matching terms.
위의 세 가지 문제점 모두는, most_fields
가 단어 중심(term-centric) 이라기 보다는, field 중심(field-centric) 이라는 사실에서 기인한다. 실제로 관심을 가지는 것은 대부분이 일치하는 단어(terms) 인데, 대부분이 일치하는 fields 를 검색한다.
First we’ll look at why these problems exist, and then how we can combat them.
먼저, 이러한 문제가 왜 존재하는지, 어떻게 방지할 수 있는지 검토해 보자.
Problem 1: Matching the Same Word in Multiple Fieldsedit
Think about how the most_fields
query is executed: Elasticsearch generates a separate match
query for each field and then wraps these match queries in an outer bool
query.
most_fields
query가 실행되는 방법에 대해 생각해 보자. Elasticsearch는 각 field 별로 match
query를 생성하고, 바깥에서 bool
query로 이들 match query를 감싼다.
We can see this by passing our query through the validate-query
API:
validate-query
API에 query를 전달해 보면, 이를 확인할 수 있다.
GET /_validate/query?explain { "query": { "multi_match": { "query": "Poland Street W1V", "type": "most_fields", "fields": [ "street", "city", "country", "postcode" ] } } }
which yields this explanation
:
아래와 같은 explanation
을 볼 수 있다.
(street:poland street:street street:w1v) (city:poland city:street city:w1v) (country:poland country:street country:w1v) (postcode:poland postcode:street postcode:w1v)
You can see that a document matching just the word poland
in two fields could score higher than a document matching poland
and street
in one field.
두 개 의 field에서 poland
라는 단어가 일치하는 document가, 하나의 field에서 poland
와, street
가 일치하는 document보다, 더 높은 score를 가지는 것을 볼 수 있다.
Problem 2: Trimming the Long Tailedit
In Controlling Precision, we talked about using the and
operator or the minimum_should_match
parameter to trim the long tail of almost irrelevant results. Perhaps we could try this:
Controlling Precision에서, 덜 관련 있는 불필요한 결과를 정리하기 위해, and
operator나 minimum_should_match
매개변수의 사용에 대하여 이야기했었다. 아마 이런 query를 실행했을 것이다.
{ "query": { "multi_match": { "query": "Poland Street W1V", "type": "most_fields", "operator": "and", "fields": [ "street", "city", "country", "postcode" ] } } }
However, with best_fields
or most_fields
, these parameters are passed down to the generated match
queries. The explanation
for this query shows the following:
하지만, best_fields
나 most_fields
에서, 이들 매개변수는 생성된 match
query에 전달된다. 이 query에 대한 explanation
은 아래와 같다.
(+street:poland +street:street +street:w1v) (+city:poland +city:street +city:w1v) (+country:poland +country:street +country:w1v) (+postcode:poland +postcode:street +postcode:w1v)
In other words, using the and
operator means that all words must exist in the same field, which is clearly wrong! It is unlikely that any documents would match this query.
즉, and
operator를 사용한다는 것은 모든 단어가 동일한 field에 반드시 존재해야 한다는 것을 의미하는데, 이것은 명백히 잘못되었다. 어떤 document도 이 query와 일치하지 않을 것이다.
Problem 3: Term Frequenciesedit
In What Is Relevance?, we explained that the default similarity algorithm used to calculate the relevance score for each term is TF/IDF:
What Is Relevance?에서, 각 단어에 대한 relevance score를 계산하는데 사용되는, 기본 유사성 알고리즘이 TF/IDF 라는 것을 설명한 바 있다.
- Term frequency
The more often a term appears in a field in a single document, the more relevant the document.
단일 document에서 특정 field에 어떤 단어가 더 자주 나타날수록, document는 더 관련있다.
- Inverse document frequency
The more often a term appears in a field in all documents in the index, the less relevant is that term.
index에 있는 모든 document의 특정 field에 단어가 더 자주 나타날수록, 해당 단어는 관련성이 더 낮다.
When searching against multiple fields, TF/IDF can introduce some surprising results.
다중 field 검색 시, TF/IDF는 조금 놀라운 결과를 보여준다.
Consider our example of searching for "Peter Smith" using the first_name
and last_name
fields.Peter is a common first name and Smith is a common last name—both will have low IDFs. But what if we have another person in the index whose name is Smith Williams? Smith as a first name is very uncommon and so will have a high IDF!
first_name
과 last_name
field를 사용하는, "Peter Smith" 를 검색하는 예를 생각해 보자. Peter는 흔한 first name이고, Smith는 흔한 last name이다. 둘 모두 낮은 IDF를 가질 것이다. Smith Williams 이라는 이름을 가진 또 다른 사람이, index에 있다면 어떻게 될까? Smith는 아주 흔하지 않은 first name이고, 따라서 높은 IDF를 가질 것이다.
A simple query like the following may well return Smith Williams above Peter Smith in spite of the fact that the second person is a better match than the first.
아래의 간단한 query는, 두 번째가 첫 번째보다 더 잘 일치한다는 사실에도 불구하고, Smith Williams 를 Peter Smith 보다 앞서서 돌려줄 것이다.
{ "query": { "multi_match": { "query": "Peter Smith", "type": "most_fields", "fields": [ "*_name" ] } } }
The high IDF of smith
in the first name field can overwhelm the two low IDFs of peter
as a first name and smith
as a last name.
first name field에 있는, 높은 IDF의 smith
는, first name으로서의 peter
와, last name으로서의 smith
둘 모두를 압도할 수 있다.
Solutionedit
These problems only exist because we are dealing with multiple fields. If we were to combine all of these fields into a single field, the problems would vanish. We could achieve this by adding a full_name
field to our person
document:
이런 문제점은 다중 fields를 다루기 때문에 발생한다. 만약 이러한 field를 하나의 field로 조합한다면 문제점은 사라질 것이다. person
document에 full_name
field를 추가하여, 이것을 할 수 있다.
{ "first_name": "Peter", "last_name": "Smith", "full_name": "Peter Smith" }
When querying just the full_name
field:
full_name
field만 검색할 경우
Documents with more matching words would trump documents with the same word repeated.
더 많이 일치하는 단어를 가진 document는 동일한 단어를 반복해서 가지고 있는 document보다 우위에 있다.
The
minimum_should_match
andoperator
parameters would function as expected.minium_should_match
와operator
매개변수는 예상대로 동작할 것이다.The inverse document frequencies for first and last names would be combined so it wouldn’t matter whether Smith were a first or last name anymore.
first_name, last_name에 대한 IDF는 조합될 것이다. 따라서 Smith가 first name이든 last name이든 더 이상 관계없다.
While this would work, we don’t like having to store redundant data. Instead, Elasticsearch offers us two solutions—one at index time and one at search time—which we discuss next.
이렇게 할 수 있지만, 중복된 데이터를 저장해야 하는 것이 마음에 들지 않을 것이다. Elasticsearch는 두 가지 해법(하나는 색인 시에, 또 다른 하나는 검색 시에)을 가지고 있는데, 바로 다음에 이야기할 것이다.
'2.X > 2. Search in Depth' 카테고리의 다른 글
2-3-06. Most Fields (0) | 2017.09.30 |
---|---|
2-3-07. Cross-fields Entity Search (0) | 2017.09.30 |
2-3-09. Custom _all Fields (0) | 2017.09.28 |
2-3-10. cross-fields Queries (0) | 2017.09.28 |
2-3-11. Exact-Value Fields (0) | 2017.09.28 |