해당 글은 엘라스틱 스택 개발부터 운영까지라는 책 중 4장을 정리하여 쓴 글입니다.
1부에 이어서 2부에서는 전문 쿼리, 매치 쿼리, 용어 쿼리, 멀티 매치 쿼리, 범위 쿼리, 논리 쿼리, 패턴 쿼리에 대해서 알아보려고 한다.
엘라스틱서치는 검색 쿼리로써 리프 쿼리, 복합 쿼리로 나눌 수 있다.
리프 쿼리 ? 특정 필드에서 용어를 찾는 쿼리로 match, term, range 등이 있다.
복합 쿼리 ? bool 쿼리 등이 있다.
전문 쿼리 (Full Text Query)와 용어 수준 쿼리 (Term level Query)를 자세히 보고 복합 쿼리인 논리 쿼리로 개념을 확장하려고 한다.
전문 쿼리와 용어 수준 쿼리
전문 쿼리 ? 전문 검색을 하기 위해 사용되며, 전문 검색을 할 필드는 인덱스 매핑 시 텍스트 타입으로 매핑해야 한다.
용어 수준 쿼리 ? 정확히 일치하는 용어를 찾기 위해 사용되며, 인덱스 매핑 시 필드를 키워드 타입으로 매핑해야 한다.
용어 수준 쿼리는 정확한 결과를 얻기 위한 권장사항이다.
전문쿼리와 용어 수준 쿼리는 분석기를 거치는지? 거치지 않는지에 대한 차이가 있다. 선택을 하게 된다면 전문 쿼리는 텍스트 타입 필드에서 검색어를 찾을 때 사용하고, 용어 수준 쿼리는 키워드, 숫자형, 범위형, 타입의 필드에서 검색어를 찾을 때 사용하자.
매치 쿼리 (MATCH)
매치 쿼리 ? 대표적 전문 쿼리, 전체 텍스트 중에서 특정 용어나 용어들을 검색할 때 사용한다.
단일 검색 ? 일반적인 분석기를 사용했다면 대문자를 소문자로 변경하기 때문에 대소문자 상관없이 검색이 된다.
복수 검색 ? "mary baily"로 검색할 때 단어 간의 공백이 OR로 인식하게 되기 때문에 두 단어가 모두 [mary, bailey]로 토큰화되어 mary, bailey가 하나라도 포함된 도큐먼트가 있다면 매칭되었다고 판단되어 검색이 된다.
복수 검색에서 모두 해당되게 하려면 어떻게 해야 할까? 그러면 query에 operator의 속성을 and로 바꿔주면 된다.
매치 프레이즈 쿼리 (Match Phrase Query)
매치 프레이즈 쿼리는 2개 이상의 단어가 연결되어 만들어지는 단어다. 즉 2개 이상의 단어가 순서까지 비슷하게 검색되어져야 한다.
주의해야할 점은 매치 프레이즈 쿼리는 검색 시 많은 리소스를 요구하기 때문에 자주 사용하는 것은 좋지 않다.
용어 쿼리(Term Query)
용어 쿼리는 매치 쿼리와 비슷하지만 큰 차이점이 있다. 매치 쿼리는 전문 쿼리에 속하기 때문에 검색어인 분석기에 의한 토큰화가 되어 매칭이 되지만, 용어 검색은 용어 수준 쿼리에 속하기 때문에 분석기에 의해 토큰화되지 않는다. 즉 분석기를 거치지 않았기 때문에 대소문자도 정확히 맞아야 한다.
추가로 검색어를 찾을 떄 분석기에 의해 대문자 소문자에 의한 부분도 신경써서 검색을 하여한다. 현재는 오른쪽의 검색 결과가 모두 토큰화 되어서 [mary, bailey, greene, sanders] 로 검색을 하여야 나온다. 즉 mary로 검색했을 때는 나오고 Mary로 검색하면 안나온다는 것이다.
용어 쿼리는 terms 쿼리를 통하여 여러 용어들 중에 일치하는 검색 결과를 내줄 수도 있다. 위의 예시로는 Monday 혹은 Sunday인 도큐먼트를 얻어낼 수 있다.
멀티 매치 쿼리 (Multi Match Query)
멀티 매치 쿼리 ? 하나의 필드를 기준으로 찾는 상황이 아닌 여러 필드를 모두 검색해야할 때 사용해야하는 방법
멀티 매치 쿼리는 mult_match 를 사용하며 필드 조건은 fields에 써놓으면 된다. 검색에 대한 스코어 계산은 필드에 대해서 개별 스코어를 구한 다음에 그중 가장 큰 값을 대표 스코어로 구한다. 추가로 와일드 카드를 통하여 유사한 필드에 대한 검색, 필드에 가중치를 두어 특정 필드에 스코어를 추가하는 방법이 있다.
멀티 매치 쿼리는 type을 지정할 수 있다. type의 종류는 best_fields(default), most_fields, cross_fields, phrase, phrase_prefix, bool_prefix가 있습니다. 이러한 type에 대한 설정은 _score 계산에 영향력을 주기 때문에 전문 검색 시에 우수하게 사용할 수 있을 것이라고 생각합니다.
범위 쿼리
말 그대로 범위 쿼리다. 특정 날짜나 숫자의 범위를 지정해 범위 안에 포함된 데이터들을 검색할 때 사용한다. 날짜/숫자/IP 타입의 데이터는 범위 쿼리가 가능하지만 문자형, 키워드 타입의 데이터에는 범위 쿼리를 사용할 수 없다.
범위 쿼리 설명은 공식 문서에서 더 확인 해볼 것을 추천한다.
https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-range-query.html
Range query | Elasticsearch Guide [8.0] | Elastic
Returns documents that contain terms within a provided range. The following search returns documents where the age field contains a term between 10 and 20. response = client.search( body: { query: { range: { age: { gte: 10, lte: 20, boost: 2 } } } } ) puts
www.elastic.co
논리 쿼리
논리 쿼리 ? 복합 쿼리로 앞에서 배웠던 쿼리를 조합할 수 있다. 매치 쿼리나 용어 쿼리는 단독으로는 검색할 수만 있다. 그러나 복합적으로 쿼리를 검색해야할 때가 있는데, 이때 논리 쿼리를 사용해야 한다.
논리 쿼리는 4개의 타입을 지원한다.
must | 쿼리를 실행하여 참인 다큐먼트를 찾는다. |
복수의 쿼리를 실행하면 AND 연산을 한다. | |
must_not | 쿼리를 실행하여 거짓인 도큐먼트를 찾는다. |
다른 타입과 같이 사용할 경우 도큐먼트에서 제외한다. | |
should | 단독으로 사용 시 쿼리를 실행하여 참인 도큐먼트를 찾는다. |
복수의 쿼리를 실행하면 OR 연산을 한다. | |
다른 타입과 같이 사용할 경우 스코어에만 활용된다. | |
filter | 쿼리를 실행하여 '예/아니요' 형식의 필터 컨텍스트를 수행한다. |
must
must ? 참인 도큐먼트를 찾는다. 그리고 복수의 쿼리를 실행하면 AND 연산을 실행한다.
must_not
must_not ? 도큐먼트에서 제외할 쿼리를 실행한다.
should
should ? 하나의 쿼리를 사용한다면 must 타입과 같은 결과를 얻는다. 하지만 복수개의 쿼리를 사용한다면 OR 조건으로 되면서 더 많은 도큐먼트가 검색되는 것을 확인할 수 있다. 이렇게 검색 된 쿼리는 검색 결과에 영향을 주지 않고 스코어에만 영향을 준다.
filter
filter ? must와 같이 동작을 하지만 필터 컨텍스트로 동작하기 때문에 유사도 스코어에 영향을 미치지 않는다. 즉 예/아니요 두 가지 결과만 제공할 뿐 요사도를 고려하지 않는다.
패턴 검색
패턴 검색 ? 검색어가 길거나 검색어를 정확히 알지 못하는 경우 사용한다. 와일드카드 쿼리와 정규식 쿼리 방법이 있다. 패턴 검색은 많은 리소스를 사용하기 때문에 권장하지 않지만 필요할 때 효율적으로 사용하면 좋다고 한다.
와일드카드 쿼리 ? *, ?라는 두 가지 기호를 사용할 수 있다.
*는 공백까지 포함하여 글자 수에 상관없이 모두 문자를 매칭한다.
?는 오직 한 문자만 매칭할 수 있다.
정규식 쿼리 ? *, ., +, ?, (), [] 를 사용할 수 있다.
*은 앞 문자와 같은 문자가 0번, 혹은 여러 번 반복되면 매칭되었다고 판단한다.
점(.)은 하나의 문자를 의미하고 어떤 문자가 와도 상관없이 매칭되었다고 판단한다.
+는 앞 문자와 같은 문자가 한 번 이상 반복되면 매칭되었다고 판단한다.
?는 앞 문자와 같은 문자가 0번 혹은 한 번 나타나면 매칭되었다고 판단한다.
()는 그룹핑하여 반복되는 문자들을 매칭한다.
[]는 클래스화하여 특정 범위의 문자들을 매칭한다.
마침
패턴 검색을 끝으로 검색에 대한 부분은 끝을 낸다.
회고
회사를 옮기고 나서 엘라스틱서치가 다른 sql에 비해서 검색하는 방법이 다르다고 깨달았다. 그래서 좀 벽이 있었지만, 요번 기회로 엘라스틱서치에 검색에 대해서 익숙해질 수 있었고, 나름대로 한번 더 정리를 할 수 있는 시간이 되었다. 앞으로 효율성 있는 쿼리를 짤 수 있도록 더욱 노력해보겠다.
'ELK > ELK 개발부터 운영까지' 카테고리의 다른 글
살려줘!! HyperLogLog (2) | 2022.03.18 |
---|---|
엘라스틱서치(elasticsearch) 집계 (0) | 2022.03.09 |
엘라스틱서치(elasticSearch) 검색 - 1부 (0) | 2022.03.01 |
엘라스틱서치(elasticSearch) 기본 - 2부 (0) | 2022.02.23 |
엘라스틱서치(elasticSearch) 기본 - 1부 (0) | 2022.02.23 |