## 개요 - 분산 검색엔진 - 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