본문 바로가기
카테고리 없음

ElasticSearch 검색 API

by 신입같은 3년차 2021. 2. 19.

이번 포스팅에서는 앞에서 생성한 데이터들을 어떻게 조회할것인지에 대해 알아보겠습니다.

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값이 정렬되지 않는다.

}

반응형

댓글