Full-text search is a battle between recall—returning all the documents that are relevant—and precision—not returning irrelevant documents. The goal is to present the user with the most relevant documents on the first page of results.
full-text 검색은 recall(적합한 document 모두를 반환하는)과 정확성(precision)(부적합한 document를 반환하지 않는)의 전쟁이다. 결과의 첫 번째 page에 가장 적합한 document를 사용자에게 제시하는 것이 목표이다.
To improve recall, we cast the net wide—we include not only documents that match the user’s search terms exactly, but also documents that we believe to be pertinent to the query. If a user searches for "quick brown fox", a document that contains fast foxes
may well be a reasonable result to return.
recall을 향상시키기 위해, 검색 범위를 넓게 잡는다. 사용자가 검색한 단어와 정확히 일치하는 document만 포함하는 것이 아니라, query에 관련된 것으로 생각되는 document도 포함시킨다. 사용자가 "quick brown fox" 를 검색했다면, fast foxes
를 포함하는 document도 반환할 적절한 결과가 될 것이다.
If the only pertinent document that we have is the one containing fast foxes
, it will appear at the top of the results list. But of course, if we have 100 documents that contain the words quick brown fox
, then the fast foxes
document may be considered less relevant, and we would want to push it further down the list. After including many potential matches, we need to ensure that the best ones rise to the top.
관련 있는 document가, fast foxes
를 포함하는 document 하나뿐이면, 그것은 결과 목록의 상단에 나타날 것이다. 하지만 물론, quick brown fox
를 포함하는 document가 100개라면, fast foxes
를 포함하는 document는 덜 관련되어 있는 document로 간주될 것이고, 목록의 더 아래로 밀어낼 것이다. 일치할 가능성이 있는 많은 document를 포함시킨 후에, 가장 일치하는 document가 상위에 있는지 보장해야 한다.
A common technique for fine-tuning full-text relevance is to index the same text in multiple ways, each of which provides a different relevance signal. The main field would contain terms in their broadest-matching form to match as many documents as possible. For instance, we could do the following:
full-text relevance의 미세 조정을 위한 일반적인 기술은, 동일한 문장(text)을 여러 가지 방식으로 색인하는 것이고, 그 각각의 방식은 다른 relevance 신호(signal) 를 제공한다. 주 field는, 가능한 한 많은 document를 일치시키기 위해, 광범위하게 일치(broadest-matching)하는 형태의 단어를 포함할 것이다. 예를 들면
Use a stemmer to index
jumps
,jumping
, andjumped
as their root form:jump
. Then it doesn’t matter if the user searches forjumped
; we could still match documents containingjumping
.jumps
,jumping
,jumped
를 기본형(jump
)으로 색인 하기 위해, 형태소 분석기를 사용한다. 사용자가jumped
를 검색하더라도,jumping
을 포함하는 document는 여전히 일치해야 한다.Include synonyms like
jump
,leap
, andhop
.jump
,leap
,hop
와 같은 동의어를 포함한다.Remove diacritics, or accents: for example,
ésta
,está
, andesta
would all be indexed without accents asesta
.발음 구별 부호나 accents를 제거한다. 예를 들면
ésta
,está
,esta
는, accents 없이, 모두esta
로 색인된다.
However, if we have two documents, one of which contains jumped
and the other jumping
, the user would probably expect the first document to rank higher, as it contains exactly what was typed in.
그런데, 두 개의 document를 가지고 있는데, 하나는 jumped
를, 다른 하나는 jumping
을 포함하고 있다면, 아마도 사용자는 자신이 입력한 것을 정확히 포함하는, 첫 번째 document가 먼저 나올 거라 예상할 것이다.
We can achieve this by indexing the same text in other fields to provide more-precise matching. One field may contain the unstemmed version, another the original word with diacritics, and a third might use shingles to provide information about word proximity. These other fields act as signalsthat increase the relevance score of each matching document. The more fields that match, the better.
보다 정확한 일치를 위해, 동일한 문장(text)을 서로 다른 field에 색인하여, 이것을 할 수 있다. 하나의 field에는 형태소 분석을 하지 않은 버전을, 다른 field에는 발음기호를 포함한 원래의 단어를 포함하고, 그리고 또 다른 field는 단어의 근접성에 대한 정보를 제공하기 위해 사용한다. 이러한 다른 field들은, 일치하는 각 document의 relevance score를 증가시키기 위한 신호(signal) 로 동작한다. 일치하는 field가 많을수록 더 좋다.
A document is included in the results list if it matches the broad-matching main field. If it also matches the signal fields, it gets extra points and is pushed up the results list.
document가 광범위하게 일치(broad-matching)하는 주 field와 일치하면, 결과 목록에 포함된다. 만약, signal field와도 일치하면, 추가 점수를 얻어, 결과 목록의 위쪽에 위치한다.
We discuss synonyms, word proximity, partial-matching and other potential signals later in the book, but we will use the simple example of stemmed and unstemmed fields to illustrate this technique.
이 책의 뒷부분에서, 동의어, 단어 근접성, 부분 일치, 그리고 다른 가능성 있는 signal에 대해 이야기 할 것이다. 이 기술을 설명하기 위해, 형태소 분석을 한 field, 형태소 분석을 하지 않은 field의 간단한 예제를 사용할 것이다.
Multifield Mappingedit
The first thing to do is to set up our field to be indexed twice: once in a stemmed form and once in an unstemmed form. To do this, we will use multifields, which we introduced in String Sorting and Multifields:
먼저, field를 두 가지 방식(한 번은 형태소 분석을 한 형태, 또 한번은 형태소 분석을 하지 않은 형태)으로 색인하도록 설정해야 한다. 이를 위해, String Sorting and Multifields에서 소개한, 다중 field(multifields) 를 사용할 것이다.
DELETE /my_index PUT /my_index { "settings": { "number_of_shards": 1 }, "mappings": { "my_type": { "properties": { "title": { "type": "string", "analyzer": "english", "fields": { "std": { "type": "string", "analyzer": "standard" } } } } } } }
Relevance Is Broken!를 참고하자. | |
| |
|
Next we index some documents:
다음 단계로, 몇 개의 document를 색인하자.
PUT /my_index/my_type/1 { "title": "My rabbit jumps" } PUT /my_index/my_type/2 { "title": "Jumping jack rabbits" }
Here is a simple match
query on the title
field for jumping rabbits
:
title
field에서 jumping rabbits
을 검색하는, 간단한 match
query가 아래에 있다.
GET /my_index/_search { "query": { "match": { "title": "jumping rabbits" } } }
This becomes a query for the two stemmed terms jump
and rabbit
, thanks to the english
analyzer. The title
field of both documents contains both of those terms, so both documents receive the same score:
english
analyzer로 인해, 형태소 분석된 두 단어 jump
, rabbit
으로 검색하게 된다. 두 document의 title
field는 이들 단어 모두를 포함하고 있어서, 두 document는 동일한 score를 가진다.
{ "hits": [ { "_id": "1", "_score": 0.42039964, "_source": { "title": "My rabbit jumps" } }, { "_id": "2", "_score": 0.42039964, "_source": { "title": "Jumping jack rabbits" } } ] }
If we were to query just the title.std
field, then only document 2 would match. However, if we were to query both fields and to combine their scores by using the bool
query, then both documents would match (thanks to the title
field) and document 2 would score higher (thanks to the title.std
field):
title.std
field로만 query하면, document 2만 일치한다. 그러나 두 field 모두에게 query를 하면, bool
query를 사용하여 score를 조합 한다. 그리고 나면 두 document 모두 일치할 것이고(title
field 덕분에), document 2는 더 높은 score를 가질 것이다(title.std
field 덕분에).
GET /my_index/_search { "query": { "multi_match": { "query": "jumping rabbits", "type": "most_fields", "fields": [ "title", "title.std" ] } } }
모두 일치하는 field로부터 score를 조합하려면, |
{ "hits": [ { "_id": "2", "_score": 0.8226396, "_source": { "title": "Jumping jack rabbits" } }, { "_id": "1", "_score": 0.10741998, "_source": { "title": "My rabbit jumps" } } ] }
We are using the broad-matching title
field to include as many documents as possible—to increase recall—but we use the title.std
field as a signal to push the most relevant results to the top.
가능한 한 많은 document를 포함하기 위해(recall을 증가시키기 위해), 광범위하게 일치하는 title
field를 사용하고 있다. 그러나, 우리는 title.std
field를 가장 적합한 결과를 상위로 올리기 위한 signal 로 사용한다.
The contribution of each field to the final score can be controlled by specifying custom boost
values. For instance, we could boost the title
field to make it the most important field, thus reducing the effect of any other signal fields:
최종 score에 대한 각 field에 대한 기여도는, boost
값을 지정하여 조정한다. 예들 들어, title
field를 가장 중요한 field로 만들기 위해, 가중치를 부여할 수 있는데, 이렇게 하면 다른 signal field의 효과는 감소한다.
'2.X > 2. Search in Depth' 카테고리의 다른 글
2-3-04. Tuning Best Fields Queries (0) | 2017.09.30 |
---|---|
2-3-05. multi_match Query (0) | 2017.09.30 |
2-3-07. Cross-fields Entity Search (0) | 2017.09.30 |
2-3-08. Field-Centric Queries (0) | 2017.09.28 |
2-3-09. Custom _all Fields (0) | 2017.09.28 |