ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • List 구조 텀 분석하기와 tokenizer 설정하기
    elasticsearch 2021. 7. 6. 11:28

    elasticsearch 데이터에 아래와 같이 데이터를 입력해

    PUT my-index/_doc/1
    {
      "category": "travel,shopping,car"
    }
    
    PUT my-index/_doc/2
    {
      "category": "travel"
    }

    category 의 특정 항목이 포함된 레코드를 모두 보고 싶다.

    검색 쿼리 예:

    GET my-index/_search
    {
      "query": {
        "term": {
          "category": {
            "value": "shopping"
          }
        }
      }
    }

    이 경우 elasticsearch 에 별다른 설정없이도 잘 된다.

     

    문제

    그런데 아래 처럼 입력 후

    PUT my-index/_doc/3
    {
      "category": "1,2,3"
    }
    
    PUT my-index/_doc/4
    {
      "category": "1"
    }

    검색을 하면

    GET my-index/_search
    {
      "query": {
        "term": {
          "category": {
            "value": "2"
          }
        }
      }
    }

    _doc/3 에 해당하는 문서가 나올 것을 예상했으나 결과는 아래와 같다.

    {
      "took" : 0,
      "timed_out" : false,
      "_shards" : {
        "total" : 1,
        "successful" : 1,
        "skipped" : 0,
        "failed" : 0
      },
      "hits" : {
        "total" : {
          "value" : 0,
          "relation" : "eq"
        },
        "max_score" : null,
        "hits" : [ ]
      }
    }

    왜 일까?

     

     

    설명

    elasticsearch 에서 "travel,shopping,car" 와 "1,2,3" 을 다르게 형태소 분석을 하기 때문이다. 

    • "travel,shopping,car" 을 분석했을 때
    POST _analyze
    {
      "tokenizer": "standard",
      "text": "travel,shopping,car"
    }
    
    
    // 결과
    {
      "tokens" : [
        {
          "token" : "travel",
          "start_offset" : 0,
          "end_offset" : 6,
          "type" : "<ALPHANUM>",
          "position" : 0
        },
        {
          "token" : "shopping",
          "start_offset" : 7,
          "end_offset" : 15,
          "type" : "<ALPHANUM>",
          "position" : 1
        },
        {
          "token" : "car",
          "start_offset" : 16,
          "end_offset" : 19,
          "type" : "<ALPHANUM>",
          "position" : 2
        }
      ]
    }

     

    • "1,2,3" 을 분석했을 때
    POST _analyze
    {
      "tokenizer": "standard",
      "text": "1,2,3"
    }
    
    // 결과
    {
      "tokens" : [
        {
          "token" : "1,2,3",
          "start_offset" : 0,
          "end_offset" : 5,
          "type" : "<NUM>",
          "position" : 0
        }
      ]
    }

     

    comma 를 기준으로 형태소를 분석하기 위해서는 다음과 같이 template 을 등록해 category 항목이 comma_tokenizer 로 분석되도록 해야 한다.

    {
      "index_patterns": [
        "my-index*"
      ],
      "settings": {
        "number_of_shards": 2,
        "number_of_replicas": 1,
        "analysis": {
          "analyzer": {
            "comma_analyzer": {
              "tokenizer": "comma_tokenizer"
            }
          },
          "tokenizer": {
            "comma_tokenizer": {
              "type": "pattern",
              "pattern": ","
            }
          }
        }
      },
      "mappings": {
        "properties": {
          "category": {
            "type": "text",
            "analyzer": "comma_analyzer",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          }
        }
      }
    }

     

    혹은 category 의 값을 아래처럼 입력해 해결할 수 있다.

    PUT my-index/_doc/3
    {
      "category": ["1", "2", "3"]
    }

     

    댓글

Designed by Tistory.