이번 포스팅에서는 앞에서 생성한 데이터들을 어떻게 조회할것인지에 대해 알아보겠습니다.
ElasticSearch에서의 검색 API는 HTTP URI형태에 파라미터를 추가해 검색하는 방법
과 RESTful API 방식은 QueryDSL
을 사용하여 질의 내용을 추가하는 방식이 있습니다.
저 같은 경우는 전자보다 후자인 RESTful API 방식의 QueryDSL방식을 추천합니다.
QueryDSL을 추천하는 이유는 가독성도 좋고, JSON형식으로 다양한 표현이 가능하기때문입니다, Query의 조건을 여러개 만들거나 집계쿼리등 복잡한 쿼리를 작성하려면 아무래도 HTTP방식보다 QueryDSL방식이 더 편하기 때문입니다.
URL로 여러단계 , 여러개의 중첩된 표현을 하기가 어렵습니다.
💡URI 방식의 검색 질의
전에 했던 포스팅에 보면 id를 주지 않고 데이터를 색인했었습니다.
URI 방식으로 그 데이터를 조회해보겠습니다.
GET /movie/_doc/v9jvsHcBBGvHH649exkJ
// 조회 결과
{
"_index" : "movie",
"_type" : "_doc",
"_id" : "v9jvsHcBBGvHH649exkJ",
"_version" : 1,
"_seq_no" : 2,
"_primary_term" : 1,
"found" : true,
"_source" : {
"movieCd" : "1",
"movieNm" : "반지의 제왕3 왕의 귀환",
"movieNmEn" : "The Lord Of The Rings: The Return Of The King",
"prdtYear" : "2003",
"repNationNm" : "뉴질랜드",
"regGenreNm" : "판타지"
}
}
// _id 가 없는경우의 조회 결과
{
"_index" : "movie",
"_type" : "_doc",
"_id" : "v9jvsHcBBGvHH649exkJ1",
"found" : false
}
이번에는 _id가 아니라 q
파라미터를 통해 해당하는 데이터를 조회해 보겠습니다. q
파라미터는 용어와 일치하는 문서만 조회합니다.
POST /movie/_search?q=판타지
//조회 결과
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 3,
"successful" : 3,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 0.18232156,
"hits" : [
{
"_index" : "movie",
"_type" : "_doc",
"_id" : "v9jvsHcBBGvHH649exkJ",
"_score" : 0.18232156,
"_source" : {
"movieCd" : "1",
"movieNm" : "반지의 제왕3 왕의 귀환",
"movieNmEn" : "The Lord Of The Rings: The Return Of The King",
"prdtYear" : "2003",
"repNationNm" : "뉴질랜드",
"regGenreNm" : "판타지"
}
}
]
}
}
}
검슥을 하였다면 아마 다음과 같이 판타지
라는 단어가 들어간 Document들을 가져왓을 것입니다.
timed_out을 보면 총 시간과 결과를 볼수 있으며 _shards를 통해 반환한 샤드의 수와 , 실패한 샤드의 수를 알 수 있으며, hits에서는 판타지
라는 단어가 있는 Document 문서와함께 가장높은 상위 10개의 Document를 가져옵니다.
예제를 조금더 진행해보겠습니다.
만약 전체적인 필드에서 판타지
를 조회하는것이 아니라 특정 필드에서 조회하고 싶다면 어떻게 해야할까요 그때는 q
파라미터에 key:value형식으로 추가하면됩니다.
이번 예에서는 movieNm에 귀환
이라는 단어가 들어간 문서를 찾는다고 해보겠습니다.
POST /movie/_search?q=movieNm:귀환
// 실행 결과
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 3,
"successful" : 3,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 0.18232156,
"hits" : [
{
"_index" : "movie",
"_type" : "_doc",
"_id" : "v9jvsHcBBGvHH649exkJ",
"_score" : 0.18232156,
"_source" : {
"movieCd" : "1",
"movieNm" : "반지의 제왕3 왕의 귀환",
"movieNmEn" : "The Lord Of The Rings: The Return Of The King",
"prdtYear" : "2003",
"repNationNm" : "뉴질랜드",
"regGenreNm" : "판타지"
}
}
]
}
}
다음과 같이 movieNm에 귀환이 들어간 Document만을 검색해 옵니다.
지금까지 URI를 통해 데이터를 조회하여보았습니다. 그렇다면 이제부터 RequestBody방식의 검색질의는 어떻게 하는지 알아보겠습니다
💡 Request Body 방식의 검색질의
URI 검색질의는 여러필드를 각각 다른 검색어로 질의하는 방법이 어렵습니다, 쿼리도 길어지고 복잡해지기 때문입니다.
이럴때 RequestBody를 써서 질의하면 URI 질의보다 좀더 쉽고 편하게 표현할 수 있습니다.
위에서 사용한 URI 방식의 질의 들을 RequestBody방식으로 변경해 보겠습니다.
GET /movie/_search
{
"query": {
"term": {
"movieNm": "귀환"
}
}
}
위에있는 RequestBody 형식의 검색질의로 변경한 내용입니다. 개인적일수 있지만 뭘하려는지 의도를 바로 파악할 수 있었습니다.
쿼리 구문은 다음과 같이 여러개의 키를 조합해 객체의 키 값으로 사용할 수 있습니다.
size
: # 쿼리 실행시 몇개의 Document를 반환할지 설정합니다. default 값은 10
from
# 어느 위치부터 반환할지 정합니다. 0부터 시작하면 서 size가 default 라면 0~10건의 데이터를 반환합니다 default 값은 0
sort
# 특정 필드를 기준으로 정렬합니다. asc, desc를 통해 오름차순 내림차순을 설정할 수 있다.
query
:{
# 검색하고자 하는 조건을 이곳에 정의한다.
}
filter
: {
# 검색 결과 중 특정한 값을 다시 보여준다.
# 결과 내에서 재검색할 때 사용하는 기능중 하나이다.
# 필터를 사용하게 되면 자동으로 score값이 정렬되지 않는다.
}
댓글