Elasticsearch 검색어에서 속성 추출

By | 2021년 11월 10일
Table of Contents

Elasticsearch 검색어에서 속성 추출

간단하지만 괜찮은 아이디어가 생각났다.

브랜드/카테고리/상품속성 인덱스를 생성한다.

검색어를 가지고 각각의 인덱스를 검색한다.

검색된 결과가 검색어에 포함된 속성이 된다.

예를들어 빨간 우산 을 키워드로 검색했을 때,
상품속성 인덱스에 검색하면 빨간 이 검색결과로 나올 것이고,
그 검색결과가 검색어에 포함된 속성이 된다.

nori 설치

ngram + synonym 조합으로 간단하게 형태소분석 없이 진행하려 하였으나,
CJK 관련해서 오작동 하는듯 하다.

결국 nori 형태소 분석으로 방향을 정했다.

bin/elasticsearch-plugin install --batch analysis-nori

동의어 사전 생성

/usr/share/elasticsearch/config/analysis/synonyms_brand.txt

0100,공백
mmmg,밀리미터밀리그람,엠엠엠지
ithinkso,아이띵소
iconic,아이코닉

/usr/share/elasticsearch/config/analysis/synonyms_category.txt

t-shirt,티셔츠
diary,다이어리
umbrella,우산
pouch,파우치

/usr/share/elasticsearch/config/analysis/synonyms_attribute.txt

red,빨강,빨간,레드
black,검정,검은,블랙
280mm,280
1800mm,1800

인덱스 생성

curl -XDELETE 'localhost:9200/att_brand_info?pretty'
curl -XDELETE 'localhost:9200/att_category_info?pretty'
curl -XDELETE 'localhost:9200/att_attribute_info?pretty'
curl -XPUT 'nb.skyer9.pe.kr:9200/att_brand_info?pretty' -H 'Content-Type: application/json' -d'
{
  "settings": {
    "index": {
      "number_of_replicas": "0",
      "analysis": {
        "analyzer": {
          "nori_analyzer": {
            "tokenizer": "nori_tokenizer",
            "filter": [
              "lowercase",
              "cjk_width",
              "synonym_filter"
            ]
          }
        },
        "filter": {
          "synonym_filter": {
            "type": "synonym",
            "synonyms_path": "analysis/synonyms_brand.txt",
            "updateable": true
          }
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "brand_name": {
        "type": "text",
        "search_analyzer": "nori_analyzer"
      }
    }
  }
}'
curl -XPUT 'nb.skyer9.pe.kr:9200/att_category_info?pretty' -H 'Content-Type: application/json' -d'
{
  "settings": {
    "index": {
      "number_of_replicas": "0",
      "analysis": {
        "analyzer": {
          "nori_analyzer": {
            "tokenizer": "nori_tokenizer",
            "filter": [
              "lowercase",
              "cjk_width",
              "synonym_filter"
            ]
          }
        },
        "filter": {
          "synonym_filter": {
            "type": "synonym",
            "synonyms_path": "analysis/synonyms_category.txt",
            "updateable": true
          }
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "category": {
        "type": "text",
        "search_analyzer": "nori_analyzer"
      }
    }
  }
}'
curl -XPUT 'nb.skyer9.pe.kr:9200/att_attribute_info?pretty' -H 'Content-Type: application/json' -d'
{
  "settings": {
    "index": {
      "number_of_replicas": "0",
      "analysis": {
        "analyzer": {
          "nori_analyzer": {
            "tokenizer": "nori_tokenizer",
            "filter": [
              "lowercase",
              "cjk_width",
              "synonym_filter"
            ]
          }
        },
        "filter": {
          "synonym_filter": {
            "type": "synonym",
            "synonyms_path": "analysis/synonyms_attribute.txt",
            "updateable": true
          }
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "attribute_name": {
        "type": "text",
        "search_analyzer": "nori_analyzer"
      }
    }
  }
}'

데이타 입력

brand.json

{ "index": { "_index": "att_brand_info", "_type": "_doc" } }
{ "brand_name": "ithinkso" }
{ "index": { "_index": "att_brand_info", "_type": "_doc" } }
{ "brand_name": "mmmg" }
{ "index": { "_index": "att_brand_info", "_type": "_doc" } }
{ "brand_name": "iconic" }

category.json

{ "index": { "_index": "att_category_info", "_type": "_doc" } }
{ "category": "t-shirt" }
{ "index": { "_index": "att_category_info", "_type": "_doc" } }
{ "category": "diary" }
{ "index": { "_index": "att_category_info", "_type": "_doc" } }
{ "category": "umbrella" }

attribute.json

{ "index": { "_index": "att_attribute_info", "_type": "_doc" } }
{ "attribute_name": "red", "attribute_type": "color" }
{ "index": { "_index": "att_attribute_info", "_type": "_doc" } }
{ "attribute_name": "black", "attribute_type": "color" }
{ "index": { "_index": "att_attribute_info", "_type": "_doc" } }
{ "attribute_name": "280mm", "attribute_type": "size" }
{ "index": { "_index": "att_attribute_info", "_type": "_doc" } }
{ "attribute_name": "180cm", "attribute_type": "size" }
curl -XPOST 'localhost:9200/_bulk?pretty' -H 'Content-Type: application/json' --data-binary @brand.json
curl -XPOST 'localhost:9200/_bulk?pretty' -H 'Content-Type: application/json' --data-binary @category.json
curl -XPOST 'localhost:9200/_bulk?pretty' -H 'Content-Type: application/json' --data-binary @attribute.json

검색어 analyze

curl -XGET 'localhost:9200/att_brand_info/_analyze?pretty' -H 'Content-Type: application/json' -d'
{
  "analyzer": "synonym_analyzer",
  "text": "아이코닉검정우산"
}'
curl -XGET 'localhost:9200/att_category_info/_analyze?pretty' -H 'Content-Type: application/json' -d'
{
  "analyzer": "synonym_analyzer",
  "text": "아이코닉검정우산"
}'
curl -XGET 'localhost:9200/att_attribute_info/_analyze?pretty' -H 'Content-Type: application/json' -d'
{
  "analyzer": "synonym_analyzer",
  "text": "아이코닉검정우산"
}'

데이타 검색

검색어 아이코닉 검정 우산 에 대해,
각각 브랜드/카테고리/상품속성에 추출된다.

curl -XGET 'localhost:9200/att_brand_info/_search?pretty' -H 'Content-Type: application/json' -d'
{
  "from": 0,
  "size": 20,
  "sort": {
    "_score": "desc"
  },
  "query": {
    "bool": {
      "should": {
        "match": {
          "brand_name": "아이코닉검정우산"
        }
      }
    }
  }
}'
curl -XGET 'localhost:9200/att_category_info/_search?pretty' -H 'Content-Type: application/json' -d'
{
  "from": 0,
  "size": 20,
  "sort": {
    "_score": "desc"
  },
  "query": {
    "bool": {
      "should": {
        "match": {
          "category": "아이코닉검정우산"
        }
      }
    }
  }
}'
curl -XGET 'localhost:9200/att_attribute_info/_search?pretty' -H 'Content-Type: application/json' -d'
{
  "from": 0,
  "size": 20,
  "sort": {
    "_score": "desc"
  },
  "query": {
    "bool": {
      "should": {
        "match": {
          "attribute_name": "아이코닉검정우산"
        }
      }
    }
  }
}'

동의어 새로고침

curl -XPOST 'localhost:9200/att_brand_info/_reload_search_analyzers?pretty'
curl -XPOST 'localhost:9200/att_category_info/_reload_search_analyzers?pretty'
curl -XPOST 'localhost:9200/att_attribute_info/_reload_search_analyzers?pretty'

답글 남기기