이 문서의 허가되지 않은 무단 복제나 배포 및 출판을 금지합니다. 본 문서의 내용 및 도표 등을 인용하고자 하는 경우 출처를 명시하고 김종민(kimjmin@gmail.com)에게 사용 내용을 알려주시기 바랍니다.
지금까지 살펴본 풀 텍스트 검색은 스코어 점수 기반으로 정확도(relevancy)가 높은 결과부터 가져옵니다. Elasticsearch는 정확도를 고려하는 풀 텍스트 외에도 검색 조건의 참 / 거짓 여부만 판별해서 결과를 가져오는 것이 가능합니다. 풀 텍스트와 상반되는 이 특성을 정확값(Exact Value) 이라고 하는데 말 그대로 값이 정확히 일치 하는지의 여부 만을 따지는 검색입니다. Exact Value 에는 term, range 와 같은 쿼리들이 이 부분에 속하며, 스코어를 계산하지 않기 때문에 보통 bool 쿼리의 filter 내부에서 사용하게 됩니다.
bool : filter
bool쿼리의 filter 안에 하위 쿼리를 사용하면 스코어에 영향을 주지 않습니다. 다음 3개의 검색 결과를 비교 해 보도록 하겠습니다.
match 쿼리로 fox 검색
GET my_index/_search{"query": {"match": {"message":"fox" } }}
match 쿼리로 fox 검색 결과
{"took" : 1,"timed_out" : false,"_shards" : {"total":1,"successful":1,"skipped":0,"failed":0 },"hits" : {"total": {"value":4,"relation":"eq" },"max_score":0.32951736,"hits": [ {"_index":"my_index","_type":"_doc","_id":"1","_score":0.32951736,"_source": {"message":"The quick brown fox" } }, {"_index":"my_index","_type":"_doc","_id":"4","_score":0.32951736,"_source": {"message":"Brown fox brown dog" } }, {"_index":"my_index","_type":"_doc","_id":"2","_score":0.23470737,"_source": {"message":"The quick brown fox jumps over the lazy dog" } }, {"_index":"my_index","_type":"_doc","_id":"3","_score":0.23470737,"_source": {"message":"The quick brown fox jumps over the quick dog" } } ] }}
{"took" : 2,"timed_out" : false,"_shards" : {"total":1,"successful":1,"skipped":0,"failed":0 },"hits" : {"total": {"value":3,"relation":"eq" },"max_score":0.32951736,"hits": [ {"_index":"my_index","_type":"_doc","_id":"1","_score":0.32951736,"_source": {"message":"The quick brown fox" } }, {"_index":"my_index","_type":"_doc","_id":"2","_score":0.23470737,"_source": {"message":"The quick brown fox jumps over the lazy dog" } }, {"_index":"my_index","_type":"_doc","_id":"3","_score":0.23470737,"_source": {"message":"The quick brown fox jumps over the quick dog" } } ] }}
첫번째는 match 쿼리로 fox 를 검색했을 때 4개의 도큐먼트가 검색되었고 가장 높은 스코어는 "_score" : 0.32951736 입니다. 두번째는 검색에 match 쿼리로 quick 을 추가했을 때 3개의 도큐먼트가 검색되었고 가장 높은 스코어는 "_score" : 0.9468958 입니다. 세번째는 첫번째의 검색에 filter 구문 안에 quick 을 추가했는데 3개의 도큐먼트가 검색되었고 가장 높은 스코어는 첫번째 쿼리와 같은 "_score" : 0.32951736 입니다.
이렇게 filter는 검색에 조건은 추가하지만 스코어에는 영향을 주지 않도록 제어할 때 사용합니다. 보통 쇼핑몰에서 검색어로 정확도가 높은 상품명을 검색하면서 생산 업체를 다시 필터링 하는 등의 용도로 사용이 가능합니다.
filter 내부에서 must_not 과 같은 다른 bool 쿼리를 포함하려면 filter 내부에 bool 쿼리를 먼저 넣고 그 안에 다시 must_not 을 넣어야 합니다. 다음은 fox 를 포함하면서 dog 는 포함하지 않는 도큐먼트를 검색하는 쿼리입니다. dog 를 제외하는 must_not 쿼리가 filter 안에 있기 때문에 스코어는 fox 에만 영향을 받습니다.
위 검색에서 결과는 하나만 리턴 되었지만 스코어는 "_score" : 0.32951736으로 match 쿼리로 fox만 검색했을 때의 결과와 동일합니다.
keyword
문자열 데이터는 keyword 형식으로 저장하여 정확값 검색이 가능합니다. Keyword 에 대해서는 뒤에 매핑에서 다시 설명 하겠습니다. 아래의 쿼리는 message 필드값이 "Brown fox brown dog" 문자열과 공백, 대소문자까지 정확히 일치하는 데이터만을 결과로 리턴합니다.
keyword 필드 검색
GET my_index/_search{"query": {"bool": {"filter": [ {"match": {"message.keyword":"Brown fox brown dog" } } ] } }}