Elasticsearch 질의 DSL 정리

엘라스틱 서치를 공부하면서 봤던 DSL 쿼리를 정리해보자.


Query와 Filter의 차이

Query 일반적으로 Full Text Search(전문검색) 사용되고 필터는 YES/NO 조건의 바이너리 구분에 주로 사용된다.
쿼리는 scoring 계산되나 필터는 계산되지 않는다.
쿼리 결과는 캐싱되지 않고 필터 결과는 캐싱된다.
상대적으로 쿼리는 응답속도가 느리고 필터는 응답속도가 빠르다.


term
- term 색인이 나눠지면서 형태소로 나누어지는 저장되는 토큰등을 term이라고 한다term 쿼리는 주어진 질의문과 저장된 텀과 정확히 일치하는 문장을 찾는다.
- term으로 "name" : "cjung gglee" 라고 입력하게 되는경우에는 "cjung gglee"라는 하나의 term 찾기 때문에 결과가 나오지 않는다만약 2 이상의 term 같이 검색하고 싶을 때는 terms 쿼리를 이용해야 한다.

1
2
3
4
5
6
7
8
9
10
# terms의 사용으로 두가지 term으로 사용할 수 있다.
GET /bank/_search
{
  "query": {
    "terms": {
      "age": [3020]
    }    
  }
}
 
cs


match

match 쿼리도 term 쿼리와 마찬가지로 주어진 질의문을 색인된 term 비교해서 일치하는 도큐먼트를검색하는 질의다만 term 쿼리와 다르게 match 쿼리에서는 주어진 질의문 또한 형태소 분석을 거친 분석된 질의문으로 검색을 수행한다예를 들면 The And 검색하면 매치 쿼리는  질의문을 형태소 분석을 거쳐서 the and 질의문을 바꾸고  값을 term 비교해서 검색한다.

그리고 기본적으로 match 들어가는 데이터들은 or 검색으로 진행된다다시말하면 아래의 예에서는Diamond 또는 Street 또는 Bartlett 라는 term으로 검색한다이것을 and 바꾸고 싶은 경우에는 "operator" : "and" 옵션을 넣어주어야 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
GET /bank/_search
{
  "query": {
    "match": {
      "address": "Diamond Street Bartlett"
    }    
  }
}
 
 
operator 적용
GET /bank/_search
{
  "query": {
    "match": {
      "address": {
        "query" : "Diamond Street Bartlett",
        "operator" : "and"
      }
    }    
  }
}
 
cs


이렇게 색인을 나누고 term을 구분할 때 사용하는 형태소 분석기를 설정하기 위해서  analyzer 선택할  있다. (굳이 지금은 볼필요가 없을 것 같아 생략.)


multi_match 
여러 필드에 대한 조건을 검색할 
blance age 필드에서 값을 조회한다
두개세개 등등의 필드에서 검색한다.

1
2
3
4
5
6
7
8
9
10
GET /bank/_search
{
  "query": {
    "multi_match": {
      "fields": ["balance", "age"],
      "query": 20
    }
  }
}
 
cs


(bool) 쿼리
조건문인  조합으로 적용해서 최종 검색 결과를 찾아내자.
bool 조건에는 must, must_not, should가 존재한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
GET /bank/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "address": {
              "value": "800"
            }
          }
        }
      ],
      "must_not": [
        {
          "term": {
            "state": {
              "value": "ID"
            }
          }
        }
      ]
    }
  }
}
 
cs


문자열 쿼리(q=)
URL 검색에서 q 매개변수에 다양한 질의문을 사용해서 검색을 수행했던 방식과 동일하게 사용할수 있는 방식이다.
여러 필드의 조건으로 검색 가능

1
2
3
4
5
6
7
8
9
10
GET /bank/_search
{
  "query": {
    "query_string": {
      "default_field": "address",
      "query": "Street 800"
    }
  }
}
 
cs


접두어 쿼리

1
2
3
4
5
6
7
8
9
10
11
GET /bank/_search
{
  "query": {
    "prefix": {
      "address": {
        "value": "800"
      }
    }
  }
}
 
cs


범위 쿼리 (날짜와 시간 데이터도 범위쿼리 사용가능)

1
2
3
4
5
6
7
8
9
10
11
12
GET /bank/_search
{
  "query": {
    "range": {
      "balance": {
        "gte": 10,
        "lte": 201212132
      }
    }
  }
}
 
cs


퍼지(fuzzy) 쿼리
주어진 질의문을 레벤슈타인 거리(Levenshtein distance) 알고리즘을 기반으로 유사한 단어의 검색을 지원
주소이름이 Noble 유사한 데이터들이 출력
특정 페이지 출력도 가능

1
2
3
4
5
6
7
8
9
GET /bank/_search
{
  "query": {
    "fuzzy": {
      "address": "Noble"
    }
  }
}
 
cs


Filter 쿼리
메모리도 캐싱되고 점수도 따지지 않기 때문에 단순 검색에서는 Filter 사용하라.
예전에는 filter 밖에 있을수 있었지만 이제는 query, bool 안에 있어야 사용가능

1
2
3
4
5
6
7
8
9
10
11
12
GET /bank/_search
{
  "query": {
    "bool": {
      "filter": {
        "terms": {
          "address": ["800", "Street"]
        }
      }
    }
  }
}
cs


댓글()