Elasticsearch는 역 인덱스(inverted index) 구조를 통해 데이터를 저장한다.
Elasticsearch는 데이터가 늘어나도 찾아가야 할 행이 늘어나는 것이 아니라 역 인덱스가 가리키는 id의 배열값이 추가되는 것 뿐이기 때문에 큰 속도의 저하 없이 빠른 속도로 검색이 가능하다. 이런 역 인덱스를 데이터가 저장되는 과정에서 만들기 때문에 Elasticsearch는 데이터를 입력할 때 저장이 아닌 색인을 한다고 표현한다.
‘이순신의’로 검색하면 ‘이순’, ‘신의’로 토큰 분리 발생
GET library/_search
{
"query": {
"match": {
"bookName": "이순신의"
}
}
}

term 쿼리를 통해 ‘이순신의’ 자체 키워드를 검색하고, 접두사에 공백을 추가 match_phrase_prefix 쿼리를 날리면 ‘이순신’도 검색된다
GET library/_search
{
"query":{
"bool":{
"should":[
{"term":{
"bookName": "이순신의"
}},
{"match_phrase_prefix": {
"bookName": "이순신의 "
}}
]
}
}
}

isbn 필드 기준 하나의 doc으로 압축
GET library/_search
{
"query": {
"match": {
"bookName": "동물농장"
}
},
"collapse": {
"field": "isbn13"
}
}
public List<LibraryEs> findByBookName(String keyword) {
Pageable pageable = PageRequest.of(0, 1000);
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery()
.must(QueryBuilders.matchQuery("bookName",keyword))
.should(QueryBuilders.termQuery("bookName.keyword",keyword))
.should(QueryBuilders.matchPhraseQuery("bookName",keyword));
NativeSearchQuery nativeSearchQuery= new NativeSearchQueryBuilder().withQuery(boolQueryBuilder)
.withPageable(pageable)
.build();
SearchHits<LibraryEs> search = operations.search(nativeSearchQuery, LibraryEs.class);
List<SearchHit<LibraryEs>> searchHitList = search.getSearchHits();
List<LibraryEs> list = new ArrayList<>();
for (SearchHit<LibraryEs> libraryEsSearchHit : searchHitList) {
list.add(libraryEsSearchHit.getContent());
}
return list;
}