본문 바로가기

IT/Elasticsearch

[Elasticsearch] Elasticsearch In Action - 6 유사도 검색

6.1 일래스틱서치에서 점수를 계산하는 방법


#elasticsearch에서의 기본 점수 계산법은 TF-IDF를 기본으로 한다.

이는 TF(Term Frequency - 텀의 빈도)의 제곱근 X IDF(Inverse Document Frequency - 텀에 대한 역 문서 빈도의 제곱)

X norm(정규화 지수 : 단어의 길이에 반비례) * boost 이다. (p.243)


6.2 다른 점수 방법


#BM25 : 유사도 모듈을 반영


{

"mappings" : {

"get-together" : {

"properties" : {

"title" : "string",

"similarity" : "BM25"

}

}

}

}


6.3 부스팅


#색인 혹은 재색인시에 boost를 줄 수 있는데, 질의 시점에 부스팅을 사용하는걸 추천한다.(이유는 p.248)


6.3.2 질의 시점에 부스팅


curl 'localhost:9200/get-together/_search?pretty' -d ' {

"query" : {

"bool" : {

"should" : [

{

"match" : {

"description" : {

"query" : "elasticsearch big data",

"boost" : 2.5

}

}

},

{

"match" : {

"name" : {

"query" : "elasticsearch big data"

}

}

}

]

}

}

}'


6.5 질의 재점수로 점수에 대한 영향 줄이기


#저비용으로 점수를 다시 계산하기 위한 방법이다.


curl -XPOST 'localhost:9200/get-together/_search?pretty' -d '{

"query" : {

"match" : {

"title" : "elasticsearch"

}

},

"rescore" : {

"window_size" : "20",

"query" : {

"rescore_query" : {

"match" : {

"title" : {

"type" : "phrase",

"query" : "elasticsearch hadoop",

"slop" : 5

}

}

},

"query_weight" : 0.8,

"rescore_query_weight" : 1.3

}

}

}'

#첫 질의에서 상위 20개를 가져온 후 "rescore_query"에서 매칭되는 도큐먼트에 더 높은 점수를 다시 부여하여 정렬한다.

#저비용이지만 전체 데이터에서의 스코어링이 아니라서 살짝 아쉬운 부분이다.


6.6 function_score를 이용한 사용자 설정 점수 계산


6.6.1 가중치


#실제 점수에 weight값을 곱한다.

curl -XPOST 'localhost:9200/get-together/_search?pretty' -d ' {

"query" : {

"function_score" : {

"query" : {

"match" : {

"description" : "elasticsearch"

}

},

"functions" : [

{

"weight" : 1.5,

"filter" : {

"term" : {

"description" : "hadoop"

}

}

}

]

}

}

}'

#functions에 복수개의 가중치를 넣을수도 있다.


6.6.2 점수 결합하기


score_mode : 복수개의 함수를 어떤 방식으로 결합할지를 정한다.

boost_mode : 원본 질의와 function의 점수를 어떻게 결합할지 정한다. (sum, avg, max, min, replace)


6.6.3 field_value_factor


curl -XPOST 'localhost:9200/get-together/event/_search?pretty' -d '{

"query" : {

"function_score" : {

"query" : {

"match" : {

"title" : "elasticsearch"

}

},

"functions" : [

{

"field_value_factor" : {

"field" : "reviews",

"factor" : 2.5,

"modifier" : "ln"

}

}

]

}

}

}'


#아래와 비교해보자. "field_value_facotr"의 "field"가 없는 도큐먼트는 위 질의에서 나타나지도 않는다.

curl 'localhost:9200/get-together/event/_search?pretty' -d '{

"query" : {

"match" : {

"title" : "elasticsearch"

}

}

}'

#field_value_factor 함수에서 오는 점수는 아래와 같다.

ln(2.5 * doc['reviews'].value)

#ln 이외에도 none (default), log, log1p, log2p, ln2p, square, sqrt, seciprocal 를 사용할 수 있다.


6.6.4 스크립트


curl -XPOST 'localhost:9200/get-together/event/_search?pretty' -d '{

"query" : {

"function_score" : {

"query" : {

"match" : {

"title" : "elasticsearch"

}

},

"functions" : [

{

"script_score" : {

"script" : "Math.log(doc['attendees'].values.size() * myweight)",

"params" : {

"myweight" : 3

}

}

}

],

"boost_mode" : "replace"

}

}

}'

#에러가 나는데 나중에 확인해보자.

reason" : "failed to run inline script [Math.log(doc[attendees].values.size() * myweight)] using lang [groovy]"


6.7 다시 묶어서 보여주기


curl -XPOST 'localhost:9200/get-together/event/_search?pretty' -d '{

"query" : {

"function_score" : {

"query" : {

"match_all" : {}

},

"functions" : [

{

"weight" : 1.5,

"filter" : {

"term" : {

"description" : "hadoop"

}

}

},

{

"field_value_factor" : {

"field" : "reviews",

"factor" : 10.5,

"modifier" : "log1p"

}

}

],

"score_mode" : "sum",

"boost_mode" : "replace"

}

}

}'


6.9.1 필드 데이터 캐시


#데이터를 색인할 때 바로 캐시 메모리에 올리는 방법이다.

#이 설정이 없을 시, 첫 질의시 걸리는 시간은 길고 두번째 캐시된 이후의 질의는 빠르다.


curl -XPOST 'localhost:9200/get-together' -d '{

"mappings" : {

"group" : {

"properties" : {

"title" : {

"type" : "string",

"fielddata" : {

"loading" : "eager"

}

}

}

}

}

}'


6.9.3 필드 데이터 관리


#필드 데이터에 사용할 메모리의 제한

- indices.fielddata.cache.size: 400mb

- indices.fielddata.cache.expire: 25m


#서킷 브레이커에 필드 데이터 사용하기

curl -XPUT 'localhost:9200/_cluster/settings' {

"transient" : {

"indices.breaker.fielddata.limit" : "350mb"

}

}'


#메모리값을 무시하고 Doc values로 디스크 활용 (p277)

curl -XPOST 'localhost:9200/myindex' -d '{

"mappings" : {

"document" : {

"properties" : {

"title" : {

"type" : "string",

"index" : "not_analyzed",

"doc_values" : true

}

}

}

}

}'

'IT > Elasticsearch' 카테고리의 다른 글

[Elasticsearch] 스케일 아웃  (0) 2016.12.15
[Elasticsearch] Elasticsearch In Action - 7  (0) 2016.12.05
[Elasticsearch] Analyzer  (0) 2016.12.02
[Elasticsearch] download url  (0) 2016.12.01
[Elasticsearch] Monitoring Rest Api  (0) 2016.12.01