본문 바로가기

프로젝트/여행지 오픈 API

[ElasticSearch] Script 쿼리와 Must 쿼리

목차

     

    해당 쿼리가 헷갈려서 복습을 위해 글을 작성하였다.

     

    Script 쿼리

     

    script 쿼리는 Elasticsearch 내에서 사용자 정의 스크립트를 통해 문서를 필터링하거나 스코어링하는 데 사용되는 쿼리다. 이 스크립트는 "Painless"라는 Elasticsearch에서 제공하는 스크립트 언어를 사용하여 작성될 수 있다.

     

    script 쿼리의 주요 특징:

    1. 유연성: 사용자는 문서 필드의 값을 기반으로 복잡한 조건을 사용하여 문서를 필터링하거나 스코어링 할 수 있다.
    2. 성능 문제: 스크립트 쿼리는 다른 일반적인 쿼리에 비해 비용이 많이 들 수 있다. 따라서 대용량의 데이터셋에서 스크립트를 사용할 때는 성능에 주의해야 한다.
    3. 보안 문제: 이전 버전의 Elasticsearch에서는 Groovy와 같은 다른 스크립트 언어를 지원했지만, 이러한 스크립트 언어는 보안 취약점으로 인해 문제가 발생했다. 그래서 Elasticsearch는 "Painless"라는 보안상 안전하며 최적화된 스크립트 언어를 도입했다.

     

    # Keyword 검색 - 이경우 값이 null일때 스크립트 비교에서 에러 발생
    # 비교값에는 keyword로 전체 검색을 수행해야 하며, null값이 없도록 해야 한다.
    GET scrap_wiki_1102/_search
    {
      "_source": ["attraction_name", "content_id", "wiki_title"], 
      "query": {
        "bool": {
          "must": [
            { "script": {
                "script": {
                  "source": "doc['attraction_name.keyword'].value == doc['wiki_title.keyword'].value",
                  "lang": "painless"
                }
              }
            }
          ]
        } 
      }
    }
    
    # 올바르게 나온 결과
    GET scrap_wiki_1102/_search
    {
      "_source": ["attraction_name", "content_id", "wiki_title"],
      "query": {
        "bool": {
          "must": [
            {
              "script": {
                "script": {
                  "source": "if (doc['attraction_name.keyword'].size() != 0 && doc['wiki_title.keyword'].size() != 0) { return doc['attraction_name.keyword'].value == doc['wiki_title.keyword'].value; } return false;",
                  "lang": "painless"
                }
              }
            }
          ]
        }
      }
    }

     

     

    Must 쿼리

     

    Elasticsearch의 쿼리 DSL에서 여러 조건을 동시에 만족해야 할 때(AND 연산)는 bool 쿼리의 must 절을 사용한다.

     

    bool 쿼리는 여러 하위 쿼리를 결합할 수 있는 기능을 제공하며, must, should, must_not, filter 등의 절을 포함할 수 있다.

     

    # Keyword 검색
    GET scrap_wiki_1102/_search
    {
      "_source": ["attraction_name", "content_id", "wiki_title"], 
      "query": {
        "bool": {
          "must": [
            {"term": {"content_id": "2760707"}},
            {"term": {"wiki_title": "공원"}}
          ]
        } 
      }
    }