1. 풀 텍스트 쿼리
Match_all
// 쿼리 없이 실행
GET my_index/_search
{
"query":{
"match_all":{ }
}
}
// match_all 쿼리로 실행
GET my_index/_search
{
"query":{
"match_all":{ }
}
}
Match
GET my_index/_search
{
"query": {
"match": {
"message": "dog"
}
}
}
만약 여러검색어를 아무 Operator 없이 검색하면 Default로 OR 조건으로 검색하게 된다
GET my_index/_search
{
"query": {
"match": {
"message": "quick dog"
}
}
}
만약 Operation를 넣기 원하면 operator field를 넣어주면 된다
GET my_index/_search
{
"query": {
"match": {
"message": {
"query": "quick dog",
"operator": "and"
}
}
}
}
Match_phrase
공백을 포함한 정확한 내용을 검색시 Match_phase를 사용한다.
GET my_index/_search
{
"query": {
"match_phrase": {
"message": "lazy dog"
}
}
}
Slop을 이용해 검색어들 사이에 다른 단어가 끼어들게 만들 수 있다.
GET my_index/_search
{
"query": {
"match_phrase": {
"message": {
"query": "lazy dog",
"slop": 1
}
}
}
}
// This will return "Lazy jumping dog" and "The quick brown fox jumps over the lazy dog"
Query_string
GET my_index/_search
{
"query": {
"query_string": {
"default_field": "message",
"query": "(jumping AND lazy) OR \"quick dog\""
}
}
}
2. Bool 복합 쿼리
-
must : 쿼리가 참인 도큐먼트들을 검색합니다.
-
must_not : 쿼리가 거짓인 도큐먼트들을 검색합니다.
-
should : 검색 결과 중 이 쿼리에 해당하는 도큐먼트의 점수를 높입니다.
-
filter : 쿼리가 참인 도큐먼트를 검색하지만 스코어를 계산하지 않습니다. must 보다 검색 속도가 빠르고 캐싱이 가능합니다.
GET <인덱스명>/_search
{
"query": {
"bool": {
"must": [
{ <쿼리> }, …
],
"must_not": [
{ <쿼리> }, …
],
"should": [
{ <쿼리> }, …
],
"filter": [
{ <쿼리> }, …
]
}
}
}
// bool 쿼리로 quick 그리고 "lazy dog" 검색
GET my_index/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"message": "quick"
}
},
{
"match_phrase": {
"message": "lazy dog"
}
}
]
}
}
}
bool 쿼리로 quick 그리고 "lazy dog" 가 포함되지 않은 문서 검색
GET my_index/_search
{
"query": {
"bool": {
"must_not": [
{
"match": {
"message": "quick"
}
},
{
"match_phrase": {
"message": "lazy dog"
}
}
]
}
}
}
3. 정확도 - Relevancy
Elasticsearch는 검색 결과가 입력된 조건과 얼마나 일치하는지 계산하는 알고리즘을 가지고 있으며
이를 이용해 계산된 정확도를 기반으로 사용자가 가장 원하는 겨로가를 먼저 보여줄 수 있다.
스코어(Score) 점수
Elasticsearch는 BM25라는 수식을 이용하여 점수를 계산한다.
복잡해 보이는 이 계산에는 크게 TF, IDF 그리고 Field Length 총 3가지 요소가 사용된다.
- TF(Term Frequency) :
해당 Document에 얼마나 많은 검색어(Term)가 들어있는지 - IDF(Inverse Document Frequency) :
검색어를 포함하고 있는 Document가 많을수록 점수가 줄어듬 (많이 사용된 단어일수록 희소성이 줄어들기 때문) - Field Length :
Document의 길이가 적을수록 더 많은 점수가 늘어남
4. Bool : Should
특정 단어에 가중치를 줘서 상위로 올릴수 있다 이 때 Should를 사용하면 되겠다.
GET my_index/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"message": "fox"
}
}
],
"should": [
{
"match": {
"message": "lazy"
}
}
]
}
}
}
좀 더 활용하자면 should안에 match_phrase를 사용함으로 특정 phrase를 위로 올리고 나머지는 아래에 검색하게 만들 수 있다.
(예: 스키 장갑을 상단으로 그리고 다른종류의 장갑을 하단으로)
GET my_index/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"message": {
"query": "스키 장갑"
}
}
}
],
"should": [
{
"match_phrase": {
"message": "스키 장갑"
}
}
]
}
}
}
이렇게 should와 match_phrase를 응용하면 쇼핑몰에서 "스키 장갑" 같은 단어로 검색했을 때 스키 용품들과 각종 장갑들을 모두 가져오면서 그 중 스키 장갑을 가장 상위에 표시할 수 있습니다. slop:1을 이용하면 "스키 보드 장갑", "스키 벙어리 장갑" 같이 스키와 장갑 사이에 다른 값이 들어간 결과에도 가중치를 부여할 수 있습니다.
5. 정확한값 쿼리
Filter
참 / 거짓 여부만 판별해서 결과를 가져오는것이 가능하다(한마디로 점수에 영향을 주지 않고 추가적인 검색어를 설정할수 있다)
e.g. 보통 쇼핑몰에서 검색어로 정확도가 높은 상품명을 검색하면서 생산 업체를 다시 필터링 하는 등의 용도로 사용이 가능하다.
// 1
GET my_index/_search
{
"query": {
"match": {
"message": "fox"
}
}
}
// 2 - 3번과 같은 결과이지만 정확도가 더 높다.
GET my_index/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"message": "fox"
}
},
{
"match": {
"message": "quick"
}
}
]
}
}
}
// 3 - 2번과 같은 결과이지만 정확도는 1번과 같다
GET my_index/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"message": "fox"
}
}
],
"filter": [
{
"match": {
"message": "quick"
}
}
]
}
}
}
// must 로 fox 검색 후 must_not 으로 dog 제거
GET my_index/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"message": "fox"
}
}
],
"filter": [
{
"bool": {
"must_not": [
{
"match": {
"message": "dog"
}
}
]
}
}
]
}
}
}
Keyword
문자열, 공백, 대소문자와 정확히 일치하는 데이터만을 가져온다
GET my_index/_search
{
"query": {
"bool": {
"filter": [
{
"match": {
"message.keyword": "Brown fox brown dog"
}
}
]
}
}
}
keyword 타입으로 저장된 필드는 스코어를 계산하지 않고 정확값의 일치 여부만을 따지기 때문에 스코어가 "_score" : 0.0 으로 나오게 됩니다. 스코어를 계산하지 않기 때문에 keyword 값을 검색 할 때는 filter 구문 안에 넣도록 합니다.
6. 범위 쿼리
숫자 검색
Range Query는 "range : { <필드명>: { <파라메터>:<값> } }"으로 입력되며 4가지 Parameter를 사용합니다.
-
gte (Greater-than or equal to) - 이상 (같거나 큼)
-
gt (Greater-than) – 초과 (큼)
-
lte (Less-than or equal to) - 이하 (같거나 작음)
-
lt (Less-than) - 미만 (작음)
GET phones/_search
{
"query": {
"range": {
"price": {
"gte": 700,
"lt": 900
}
}
}
}
날짜 검색
기본적으로 Elasticsearch 에서 날짜 값은 2016-01-01 또는 2016-01-01T10:15:30 과 같이 JSON 에서 일반적으로 사용되는 ISO8601 형식을 사용합니다.
GET phones/_search
{
"query": {
"range": {
"date": {
"gt": "2016-01-01"
}
}
}
}
Format을 사용하여 여러 포맷을 이용할 수 있습니다.
// date 값이 2016-01-01 ~ 2018-01-01 사이의 데이터 검색
GET phones/_search
{
"query": {
"range": {
"date": {
"gt": "31/12/2015",
"lt": "2018",
"format": "dd/MM/yyyy||yyyy"
}
}
}
}
//date 값이 2016-01-01 의 6개월 후 부터 오늘 (2019-09-03) 의 365일 이전 사이 값 검색
GET phones/_search
{
"query": {
"range": {
"date": {
"gt": "2016-01-01||+6M",
"lt": "now-365d"
}
}
}
}
range 쿼리의 스코어는 모두 "_score" : 1.0로 동일하다. 이를 통해 알 수 있는것은 range 쿼리는 기본적으로 정확도를 계산하지 않는다.
'Elasticsearch (ELK) > Elasticsearch' 카테고리의 다른 글
7-2. 데이터 색인과 텍스트 분석(실전) - 애널라이저 & 토큰필터 (0) | 2020.05.28 |
---|---|
7-1. 데이터 색인과 텍스트 분석(이론) (0) | 2020.05.28 |
5. Elasticsearch 데이터 처리 - REST API (0) | 2020.05.26 |
4. 마스터 노드와 데이터 노드 (0) | 2020.05.26 |
3-2. Elasticsearch 시스템 구조 - 인덱스와 샤드 (0) | 2020.05.26 |