## 개요
- 분산 검색엔진
- kibana, logstash와 함께 로그 검색 용으로 많이 사용한다.
- 데이터 모델은 json을 사용하고 통신은 rest로 한다.
-
## rdb와 용어 매칭
|rdb|elasticsearch|
|-|-|
|database|Index|
|Table|Type|
|Row|Document|
|Column|Field|
|Schema|Mapping|
|Index|전부 인덱스|
|SQL|Query DSL|
## 데이터 입력 과정
- chracter filter -> tokenizer -> token filter
### character filter
- term으로 분리하기 전 전체 문장을 가공한다.
- `char_filter` 항목에 입력 필터 종류를 입력한다
- html strip, mapping, pattern replace의 3가지 종류가 있다,
### tokenizer
- 문장의 단어들을 하나씩 term으로 분리시켜서 역인덱스를 만든다.
- 한글 tokenizer는 예전에는 아리랑, 은전한닢 등을 사용했는데 6.6부터는 elasticsearch에서 공식적으로 nori를 지원해서 많이 쓴다.
- tokenizer는 1개만 적용할 수 있다.
### token filter
- 분리된 term을 가공한다.
- `filter` 항목에 필터 종류를 입력한다.
## mappings
### 문자열
- 문자열에는 text 타입과 keyword 타입이 있다.
- 필드 정의를 따로 안하면 text와 keyword가 다중 필드로 들어간다.
- text는 문자열을 입력할 때 inverted indexing을 해서 넣는다.
- keyword는 문자열 자체를 하나의 term으로 저장한다.
### 숫자 등...
## query dsl
- 검색할 때는 `GET /_search` 또는 `GET /index/_search` 에 body로 query를 보내는데 post로 요청해도 된다.
``` json
{
"query": {}
}
```
### 구조
- query: 쿼리
- aggs: 집계
- size, from: 페이지네이션
- sort: 정렬 기준 필드
- _source: 가져올 필드
- highlight: 하이라이트할 필드
- explain: 매칭 점수 정보
### full text query
- 들어온 쿼리 문자열에 각 필드의 analyzer를 적용한 후 검색한다.
- 다음 예시들은 text 타입의 title 필드를 가져온다.
#### match_all
- 전부 가져오는 쿼리여서 쿼리를 보내지 않아도 똑같이 나온다.
```json
{
query: {
"match_all": {}
}
}
```
#### match
- 쿼리 문자열이 포함된 문서를 반환하는 가장 일반적인 쿼리이다.
- 쿼리 문자열을 analyze 했을 때 여러 개의 term으로 나눠지면 기본적으로 or 조건으로 검색된다.
- `"operation": "and"`를 써서 and 조건으로 검색할 수 있다.
```json
{
"query": {
"match": {
"title": {
"query": "hello world",
"operator": "and"
}
}
}
}
```
#### match_phrase
- 쿼리 문자열을 analyze 했을 때 나온 term들의 순서가 정확히 일치하는 문서를 가져오는 쿼리이다.
- slop 옵션으로 term 사이에 다른 검색어가 끼어드는 것을 허용할 수 있다.
``` json
{
"query": {
"match_phrase": {
"title": {
"query": "hello world",
"slop": 1
}
}
}
}
```
#### match_phrase
- match_phrase와 거의 같은데 마지막 단어에 와일드카드가 붙는다.
- 자동 완성 기능에서 자주 사용된다.
``` json
{
"query": {
"match_phrase_prefix": {
"title": {
"query": "hello world"
}
}
}
}
```
#### query_string
- url에 검색할 때와 같은 문법으로 문서를 가져오는 쿼리이다.
``` json
{
"query": {
"query_string": {
"default_field": "title",
"query": "(hello AND world) OR \"welcome ground\""
}
}
}
```
### term level query
- 쿼리 문자열을 analyze하지 않고 inverted index와 바로 비교해서 검색한다.
- 숫자, 날짜처럼 구조화된 데이터에 주로 사용한다.
#### wildcard
- `*` 로 검색해서 성능이 매우 좋지 않다.
#elasticsearch #search #db