개요
엘라스틱서치는 검색엔진이니 만큼 검색은 매우 중요한 부분이라고 볼수 있다. 그래서 Query DSL이라는 특수한 쿼리 문법을 제공함으로써 다양한 검색 기능을 활용 할 수 있다. HTTP + JSON 검색으로 간편성은 제공하지만 JDBC 처럼 TCP/IP 기반 클라이언트를 제공함으로써 더 빠른 검색이 가능하게 하면 좋지 않았을까 라는 생각이 든다.
검색 API
색인시점에서는 앞에 공부한 내용처럼 분석기(standard)로 구분되어 색인될것이다.
trying out Elasticsearch => trying, out, elasticsearch
Hello Elasticsearch => hello, elasticsearch
Term | Document |
---|---|
trying | 1 |
out | 1 |
elasticsearch | 1, 2 |
hello | 2 |
그리고 검색을 아래와 같이 검색 한다면 1번 Document를 결과로 얻을수 있습니다. (자세한 검색 내용은 아래 Query DSL 에서 설명하겠습니다.)
{
"query": {
"match": {
"text": "TRY OUT"
}
}
}
검색 방식
- URI
- HTTP GET 활용
- 파라미터를 KEY=VALUE 쿼리 방식으로 전달
- 간단한 검색에서 활용
- RFC 2616 / RFC 3986 에서 얘기한것 처럼 파라미터 쿼리의 최대 크기는 없다. 하지만 DNS는 255 길이를 초과 할수 없다. (이건 문제 되기 힘듬)
- 다만 웹브라우저 이용시 크롬 기준 64k 이상 길이를 가지는 경우 표시하지 않으며 100k 까지는 이상 없이 입력 할 수 있다.
- 파라미터
- q
- optional, string
- 검색 수행 쿼리 조건
- df
- optional, string
- q에서 필드 미지정시 기본값으로 검색할 필드 지정
- analyzer
- optional, string
- q 쿼리 분석할때 사용할 분석기 지정
- analyze_wildcard
- optional, boolean
- 와일드카드(*) 검색 활성화 여부 (2019-* 이런 방식으로 2019로 시작되는 부분을 검색 할 수 있음)
- default_operator
- optional, string
- 검색 조건 연산자(AND, OR)
- _source
- optional, string (true, false 인데 왜 string?)
- 검색 결과에 본문 포함 여부
- sort
- optional, string
- 검색 결과 정렬 필드 지정
- from
- optional, integer
- 문서 시작 위치 설정(페이징)
- size
- optional, integer
- 검색 결과 개수(페이징)
- 기타
- allow_partial_search_results
- batched_reduce_size
- explain
- hit 별로 score 계산방식 설명
- lenient
- search_type
- _source_excludes
- _source 에서 제외할 필드
- _source_includes
- _source 에서 포함될 필드
- track_scores
- track_total_hits
- timeout
- terminate_after
- q
- RequestBody
- RESTful API 활용
- BODY에 JSON 형태로 Query DSL 표현
- 복잡한 검색에서 활용
Query DSL
기본 쿼리 구조
Request 구조
{
"size": "...", // 결과 개수 지정
"from": "...", // 페이징 처리를 위한 몇번째 문서 지정
"timeout": "...", // timeout 지정. timeout 이되면 에러를 반환 하는게 아니라 timeout 까지 조회된 결과 반환
"_source": "...", // 검색시 필드한 필드만 추가
"query": "...", // 검색 조건문
"aggs": "...", // 통계 및 집계 데이터
"sort": "...", // 정렬 조건
}
Response 구조
{
"took": "...", // 수행 시간
"timed_out": "...", // timeout 시
"_shards": {
"total": "...", // 전체 샤드 개수
"successful": "...", // 응답 성공 샤드 개수
"failed": "...", // 응답 실패 샤드 개수
},
"hits": {
"total": "...", // 전체 결과 갯수
"max_score": "...", // 일치 결과 스코어중 가장 높은 값
"hits": [{}, {}] // 결과 및 해당 결과의 스코어
}
}
쿼리와 필터
쿼리 컨텍스트 | 필터 컨텍스트 | |
---|---|---|
용도 | 전문 검색 시 사용 | 조건 검색시 사용 |
특징 | - 분석기에 의해 분석이 수행됨 - 연관성 score 계산 - 루씬 레벨 분석이 이루어짐으로 상대적 느림 - 결과가 캐싱되지 않음 - 디스크 연산으로 상대적 느림 |
- Yes/No로 단순 판별 - 연관성 score 계산하지 않음 - 메모리 연산 수행으로 상대적 빠름 - 결과를 내부적으로 캐싱함 |
예 | "Harry Potter" 같은 text 타입 문장 분석 | - create_year 이 2019 인지 체크 - status 가 use 인지 체크 |
검색 옵션
- multi index 검색
- , 로 구분해서 검색시 여러개 index에서 결과를 가져 올수 있다.
- index명에 와일드카드 지정 가능. 로그 데이터가 날짜별 index로 생성되는 경우(yyyy-MM-dd 같은 케이스)에서 2019-* 로 조회해서 2019년에 생성된 index 로그에서 어떤 값들을 조회 할 수 있다.
- 결과 페이징
- from, size 를 이용해서 페이징을 구현 할 수 있다.
- 다만 RDBMS 와 다르게 페이징된 값만 읽어오는게 아니라 전체를 읽어와서 필터링해서 응답을 주기 때문에 from 이 커지면 쿼리 비용이 높아진다.
- from = 0, size = 5 인 경우 5개만 조회하고 5개를 응답한다.
- from = 10, size = 5 인 경우 15개를 조회하고 5개를 응답한다.
- 결과 정렬
- sort를 이용해서 정렬
- 설정하지 않으면 score 값으로 정렬
- asc 또는 desc 를 통해서 오름차순 내림차순 정렬 가능
- _source 필드 필터링
- 범위 검색
- 날짜 또는 숫자 데이터 경우 범위 기준 질의에서 사용
- 문법
- lt (<)
- gt (>)
- lte (<=)
- gte (>=)
- operator 설정
- minimum_should_match
- OR 연산 수행시 최소 몇개 이상 매칭 되도록 설정
- fuzziness 설정
- 유사한 검색 결과 찾기 위함
- 0, 1, 2, AUTO로 설정 할 수 있다.
- AUTO
- AUTO:[low],[high] 방식으로 설정한다.
- low는 기본3, high 기본 6이다. (term 개수)
- low, high 값으로 3개 구간으로 나눠진다.
- 0 ~ 2(low - 1): fuzziness 0 적용
- 3 ~ 5(hign - 1): fuzziness 1 적용
- 6(high) ~ : fuzziness 2 적용
- AUTO
- boost 설정
- 관련성이 높은 필드나 키워드에 가중치를 더 주게 하기 위함으로 검색 정확성 높일수 있음.
Query DSL 주요 쿼리
match all
색인에 모든 문서를 검색하는 쿼리. 일반적으로 색인에 저장된 문서 확인용으로 사용함.
## POST movie_search/_search
{
"query": {
"match_all": {}
}
}
match
텍스트, 날짜, 숫자 등 포함된 문장을 형태소 분석을 통해 term으로 분리후 검색 수행. 기본적으로 검색어가 분석되어야 하는 경우 사용.
## POST movie_search/_search
{
"query": {
"match": {
"movieNm": "그대 장미"
}
}
}
multi match
match와 사용법은 비슷하나 여러개 필드에서 검색 할때 사용
## POST movie_search/_search
{
"query": {
"multi_match": {
"query": "가족",
"fields": ["movieNm", "movieNmEn"]
}
}
}
term
분석기를 통하지 않고 텍스트 형태 데이터를 조회 할때 사용한다. text 타입 경우 인지 하고 사용하자. (분석기를 통하지 않기 때문에 대소문자는 물론 완벽히 같은 값이 아닐 경우 조회 되지 않을 수 있다.) 주로 keyword 타입 검색시 사용.
## POST movie_search/_search
{
"query": {
"term": {
"movieNm": "그대 장미"
}
}
}
bool
RDBMS 처럼 여러개 조건을 AND 또는 OR로 조합해서 사용할때.
## POST movie_search/_search
{
"query": {
"bool": {
"must": [],
"must_not": [],
"should": [],
"filter": []
}
}
}
ES | RDBMS | 설명 |
---|---|---|
must | AND 칼럼 = 조건 | 반드시 만족해야 함 |
must_not | AND 칼럼 != 조건 | 반드시 만족하지 않아야 함 |
should | OR 칼럼 = 조건 | 하나 이상 만족해야 함 |
filter | IN (조건) | 조건에 포함된 결과. score 정렬 되지 않음 |
'언어 > Java' 카테고리의 다른 글
ElasticSearch 스터디 정리 (6) - 데이터 집계 2 (2) | 2020.01.16 |
---|---|
ElasticSearch 스터디 정리 (2) - 데이터 모델링 (1) | 2019.12.18 |
ElasticSearch 스터디 정리 (3) - 엘라스틱서치 분석기 (2) | 2019.12.12 |
ElasticSearch 스터디 정리 (1) (0) | 2019.11.27 |
Java 경력 기술 면접 준비(1) (0) | 2019.08.25 |