Udemy Elasticsearch - 검색 원리
August 2021 (540 Words, 4 Minutes)
Elasticsearch Udemy 강의( Complete Guide to Elastticsearch )를 보면서 document에서 document 검색 관련 정리할 내용을 기록한다.
Search Query
search query는 Elasticsearch data streams / indices의 데이터를 요청하는 쿼리를 의미한다.
Search API
https://www.elastic.co/guide/en/elasticsearch/reference/current/search-your-data.html#run-an-es-search
아래는 match
쿼리로 my-index-000001
를 탐색하는 요청 예시다.
[ 예시 ] user.id
= kimchy
인 document를 검색
GET /my-index-000001/_search
{
"query": {
"match": {
"user.id": "kimchy"
}
}
}
[ 결과 ] 기본적으로 score가 가장 높은 10개 문서를 가져온다.(문서 갯수는 설정할 수 있음)
{
"took": 5,
"timed_out": false,
"_shards": { # sharding에 대한 정보
"total": 1, # 전체 shards = 1
"successful": 1, # 성공 = 1
"skipped": 0,
"failed": 0 # 실패 = 1
},
"hits": { # 실제 결과에 대한 정보
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 1.3862942, # score 중 가장 높은 값
"hits": [ # documents
{
"_index": "my-index-000001",
"_type": "_doc",
"_id": "kxWFcnMByiguvud1Z8vC",
"_score": 1.3862942, # relevance score
"_source": {
"@timestamp": "2099-11-15T14:12:12",
"http": {
"request": {
"method": "get"
},
"response": {
"bytes": 1070000,
"status_code": 200
},
"version": "1.1"
},
"message": "GET /search HTTP/1.1 200 1070000",
"source": {
"ip": "127.0.0.1"
},
"user": {
"id": "kimchy"
}
}
}
]
}
}
Relevance
각 document의 relevance score는 _score
로 표시된다. 이 수치가 높을수록 연관성이 높다고 할 수 있다.
score는 query clause의 type에 따라 계산되는데 relevance는 full-text field의 내용이 full-text 쿼리문과 얼마나 유사한지를 판단한다.
Similarity - TFIDF
https://www.elastic.co/guide/en/elasticsearch/guide/current/relevance-intro.html
표준 유사도 측정은 TF/IDF를 기준으로 한다.
_score
계산 과정은 explain
을 옵션으로 설정함으로써 파악할 수 있다.
GET /_search?explain
{
"query" : { "match" : { "tweet" : "honeymoon" }}
}
아래와 같이 _explanation
에 각 entry는 어떤 계산이 포함되었는지를 설명한다.
"_explanation": {
"description": "weight(tweet:honeymoon in 0)
[PerFieldSimilarity], result of:",
"value": 0.076713204, # 계산값
"details": [
{
"description": "fieldWeight in 0, product of:",
"value": 0.076713204,
"details": [
{ # Term Frequency
"description": "tf(freq=1.0), with freq of:",
"value": 1,
"details": [
{
"description": "termFreq=1.0",
"value": 1
}
]
},
{ # Inverse document frequency
"description": "idf(docFreq=1, maxDocs=1)",
"value": 0.30685282
},
{ # Field-length norm
"description": "fieldNorm(doc=0)",
"value": 0.25,
}
]
}
]
}
- Term Frequency : 해당 문서에서
honeymoon
단어에tweet
필드가 얼마나 많이 등장하는가? 많이 등장할수록 연관성이 높다. - Inverse document frequency : 전체 문서에서
honeymoon
단어에tweet
필드가 얼마나 많이 등장하는가? 전체 문서에 많이 등장할수록 연관성이 낮다. - Field-length norm : 해당 문서에서
tweet
필드의 내용이 얼마나 긴가? 내용이 길수록 해당 단어가 필드와 연관성이 높다고 할 수 없다.
요약하면 특정 단어가 해당 문서에서 많이 등장하면서 전체 문서에선 등장 횟수가 적으면 그 문서를 설명하는 핵심 단어라고 할 수 있으므로 연관성이 높다. 하지만 검색하는 대상의 필드의 내용이 길수록 필드에 대한 연관성이 적으므로 전체적으로 수치를 살펴볼 필요가 있다.
왜 해당 문서가 matched
인지는 /index/type/id/_explain
에 요청하여 확인한다.
GET /us/tweet/12/_explain
{
"query" : {
"bool" : {
"filter" : { "term" : { "user_id" : 2 }},
"must" : { "match" : { "tweet" : "honeymoon" }}
}
}
}
위와 같이 요청하여,
"failure to match filter: cache(user_id:[2 TO 2])"
결과를 확인하면 user_id
로 인해 matching되지 않음을 알 수 있다.
Similarity - BM25
최근에는 BM25를 적용하여 score를 계산한다.
- https://www.elastic.co/kr/elasticon/conf/2016/sf/improved-text-scoring-with-bm25
- https://inyl.github.io/search_engine/2017/04/01/bm25.html