본문 바로가기

programmer/Elasticsearch

[Elasticsearch] POI 영문 검색 개선 팁

영문 복합 명사 검색 시 특히 한국 사람들이 보통 띄어쓰기를 하지 않거나 & 기호를 잘 사용하지 않고 심지어는 검색어를 치다가 만다.

예를들면 다양한 경우의 수가 있는대 

하기 표와 같이 사람들이 검색하는 '검색어'(POI)와 '의도'(검색 되길 원하는 결과)는 다음과 같다.

검색어 의도
cjenm cj enm 
ktg kt&g
outbacksteak outbacksteakhouse
fastfood fast food
lotteworld lotte world, lotte world tower
oneandonly, one&only one and only, one n only, one & only

이 외에도 많은 경우가 있겠지만 이를 해결할 방법을 찾아보자.

다행히 ELK 에서는 이를 처리하기 위한 다양한 필터나 토크나이저를 사용한 Analyzer를 제공한다.

애널라이저는 하기 이미지와 같이 구성된다.(이미지 참조 링크)

 

 

1. 캐릭터 필터

캐릭터 필터 중 'pattern replace' 필터를 사용해 text를 사용자 패턴으로 토크나이징 하여 사용 할 수 있다.

regex 패턴은 하기 링크에서 테스트하여 사용하면 편리하다.(manual 참조. Pattern Replace, HTML Strip, Mapping)

^(\S+)\s*(\S+)\s*(\S+) 패턴은 시작 부터 띄어쓰기 2개 사이의 text 값을 수집하는 패턴이다. ( 정규 표현식)

패턴 확인 예

 

2. 토크나이저

(manual 참조. Tokenizer )

 

3. 토큰 필터

(manual 참조. Token Filter)

asciifolding token filter: 외래어의 모든 발음 구별 부호를 제거

possessive 형태소 분석기는, english_stopenglish_keywords 그리고 english_stemmer 에 단어를 전달하기 전에, 모든 단어에서 's 를 제거

**   "english_possessive_stemmer",  "english_stemmer" 의 경우 navi 검색에서는 POI 검색을 기준으로 하므로 조사를 제거하면 안된다. 따라서 해당 분석기는 사용하지 않는 것을 추천한다. (예: notted -> not, parking -> park 로 변경 됨)

stop token: 하기 리스트에 들어간 키워드 모두 제거 [a, an, and, are, as, at, be, but, by, for, if, in, into, is, it, no, not, of, on, or, such, that, the, their, then, there, these, they, this, to, was, will, with] https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-stop-tokenfilter.html

PUT dump
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_analyzer": {
          "tokenizer": "whitespace",
          "filter": [
              "lowercase", 
              "asciifolding"
          ],
          "char_filter": [
            "my_char_filter"
          ]
        }
      },
      "char_filter": {
        "my_char_filter": {
          "type": "pattern_replace",
          "pattern": "^(\\S+)\\s*(\\S+)\\s*(\\S+)",
          "replacement": "$1 $1$2 $1$3 $1$2$3"
        },
        "my_char_filter_white": {
          "type": "pattern_replace",
          "pattern": "\\s+",
          "replacement": ""
        }
      }
    }
  },
  "mappings": {
    "_doc":{
      "properties":{
          "cname_eng": {
          "type": "keyword",
          "fields": {
            "analyze": {
              "type": "text",
              "term_vector": "yes",
              "analyzer": "my_analyzer"
            }
          }
        }
      }
    }
  }
}
POST dump/_analyze
{
  "analyzer": "my_analyzer",
  "text": "Elastic Search service test"
}

--------------------out---------------------
{
  "tokens" : [
    {
      "token" : "Elastic",
      "start_offset" : 0,
      "end_offset" : 7,
      "type" : "word",
      "position" : 0
    },
    {
      "token" : "ElasticSearch",
      "start_offset" : 8,
      "end_offset" : 21,
      "type" : "word",
      "position" : 1
    },
    {
      "token" : "Elasticservice",
      "start_offset" : 21,
      "end_offset" : 21,
      "type" : "word",
      "position" : 2
    },
    {
      "token" : "ElasticSearchservice",
      "start_offset" : 21,
      "end_offset" : 22,
      "type" : "word",
      "position" : 3
    },
    {
      "token" : "test",
      "start_offset" : 23,
      "end_offset" : 27,
      "type" : "word",
      "position" : 4
    }
  ]
}

 

PUT dump/_doc/0 
{
  "cname_eng" : "Elastic Search engine A"
}
GET dump-unified-search-44/_search
{
   "size": 10000,
  "query": {
    "bool": {
      "should": [
        {
          "query_string": {
            "query": "ElasticSearch",
            "fields": [
              "cname_eng.*^6.0",
              "fname_cname_eng*^7.0",
              "fname_eng.*^8.0"
            ]
          }
        }
      ]
    }
  }
}

--------------------out---------------------
{
  "took" : 13,
  "timed_out" : false,
  "_shards" : {
    "total" : 6,
    "successful" : 6,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 1,
    "max_score" : 1.2,
    "hits" : [
      {
        "_index" : "dump-unified-search-44",
        "_type" : "_doc",
        "_id" : "0",
        "_score" : 1.2,
        "_source" : {
          "cname_eng" : "Elastic Search engine A"
        }
      }
    ]
  }
}
반응형
사업자 정보 표시
라울앤알바 | 장수호 | 서울특별시 관악구 봉천로 13나길 58-10, 404호(봉천동) | 사업자 등록번호 : 363-72-00290 | TEL : 010-5790-0933 | Mail : shjang@raulnalba.com | 통신판매신고번호 : 2020-서울관악-0892호 | 사이버몰의 이용약관 바로가기