2017-04-16 9 views
1

하이픈을 포함하지만 공백, 마침표 또는 다른 구두점을 포함하지 않는 문자열을 색인화하려고합니다. 하이픈을 기반으로 단어를 분할하지 않고 하이픈을 색인 텍스트의 일부로 사용하고 싶습니다.하이픈에 ngram 및 단어 구분 기호가없는 Elasticsearch 사용자 정의 분석기

예를 들어, 제 6 텍스트 문자열은 다음과 같습니다

  • magazineplayon
  • magazineofhorses
  • 온라인 잡지
  • 최고의 잡지
  • 친구 -의 - 잡지
  • magazineplaygames

"재생" 또는 "잡지"로 시작하는 텍스트가 인 텍스트 인 문자열을 검색 할 수 있기를 원합니다.

"재생"이 포함 된 텍스트를 올바르게 작동 시키려면 ngram을 사용할 수있었습니다. 그러나 하이픈은 텍스트가 분리되도록하며 "잡지"가 하이픈 다음의 단어에있는 결과를 포함합니다. 나는 단지 "잡지"와 함께 문자열의 시작 부분에서 시작하는 단어를 표시하고 싶습니다.

  • magazineplayon
  • magazineofhorses
  • magazineplaygames

을 내 ElasticSearch 인덱스 샘플로 도와주세요 : "잡지"로 시작하는 경우 위의 예제를 바탕으로

만이 3이 나타납니다 :

DELETE /sample 

PUT /sample 
{ 
    "settings": { 
     "index.number_of_shards":5, 
     "index.number_of_replicas": 0, 
     "analysis": { 
      "filter": { 
       "nGram_filter": { 
        "type": "nGram", 
        "min_gram": 2, 
        "max_gram": 20, 
        "token_chars": [ 
         "letter", 
         "digit" 
        ] 
       }, 
       "word_delimiter_filter": { 
        "type": "word_delimiter", 
        "preserve_original": true, 
        "catenate_all" : true 
       } 
      }, 
      "analyzer": { 
      "ngram_index_analyzer": { 
       "type" : "custom", 
       "tokenizer": "lowercase", 
       "filter" : ["nGram_filter", "word_delimiter_filter"] 
      } 
      } 
     } 
    } 
} 
PUT /sample/1/_create 
{ 
    "name" : "magazineplayon" 
} 
PUT /sample/3/_create 
{ 
    "name" : "magazineofhorses" 
} 
PUT /sample/4/_create 
{ 
    "name" : "online-magazine" 
} 
PUT /sample/5/_create 
{ 
    "name" : "best-magazine" 
} 
PUT /sample/6/_create 
{ 
    "name" : "friend-of-magazines" 
} 
PUT /sample/7/_create 
{ 
    "name" : "magazineplaygames" 
} 

GET /sample/_search 
{ 
"query": { 
     "wildcard": { 
      "name": "*play*" 
     } 
    } 
} 

GET /sample/_search 
{ 
"query": { 
     "wildcard": { 
      "name": "magazine*" 
     } 
    } 
} 
,

내가 샘플 후 TEST를 사용하는 모든 내 생성 문을 업데이트 한 업데이트 : 단어가 그들에 "재생"대신 와일드 카드를하고 있었다 이름 만 반환 내가 다음 명령을 실행

PUT /sample/test/7/_create 
{ 
    "name" : "magazinefairplay" 
} 

수색. 이것은 올바르게 작동하고 두 개의 레코드 만 반환했습니다.

POST /sample/test/_search 
{ 
    "query": { 
     "bool": { 
      "minimum_should_match": 1, 
      "should": [ 
       {"match": { "name.substrings": "play" }} 
      ] 
     } 
    } 
} 

다음 명령을 실행하여 "magazine"으로 시작하는 이름 만 반환했습니다. 내 기대는 "온라인 잡지", "베스트 잡지"및 "잡지의 친구"가 나타나지 않을 것이라는 것이 었습니다. 그러나이 세 가지를 포함하여 7 개의 기록이 모두 반환되었습니다.

POST /sample/test/_search 
{ 
    "query": { 
     "bool": { 
      "minimum_should_match": 1, 
      "should": [ 
       {"match": { "name.prefixes": "magazine" }} 
      ] 
     } 
    } 
} 

하이픈이 사용 된 접두사를 필터링하는 방법이 있습니까?

+0

와일드 카드 대신 검색의 일부로 prefix 명령을 사용해 보았지만 도움이되지 않았습니다.

'GET/샘플/_search { "쿼리": { "앞에": { "이름": "잡지"} } } ' –

답변

4

올바른 경로에 있지만, "시작"조절 작업을 수행하려면 edge-ngram token filter을 활용하는 다른 분석기를 추가해야합니다. ngram은 주어진 단어를 "포함하는"필드를 검사 할 수 있지만 필드가 "토큰"으로 시작하는지 확인하려면 edge-ngram이 필요합니다.그것은 것, 문자열 검색을 위해 wildcard을 사용하지 마십시오

PUT /sample 
{ 
    "settings": { 
    "index.number_of_shards": 5, 
    "index.number_of_replicas": 0, 
    "analysis": { 
     "filter": { 
     "nGram_filter": { 
      "type": "nGram", 
      "min_gram": 2, 
      "max_gram": 20, 
      "token_chars": [ 
      "letter", 
      "digit" 
      ] 
     }, 
     "edgenGram_filter": { 
      "type": "edgeNGram", 
      "min_gram": 2, 
      "max_gram": 20 
     } 
     }, 
     "analyzer": { 
     "ngram_index_analyzer": { 
      "type": "custom", 
      "tokenizer": "keyword", 
      "filter": [ 
      "lowercase", 
      "nGram_filter" 
      ] 
     }, 
     "edge_ngram_index_analyzer": { 
      "type": "custom", 
      "tokenizer": "keyword", 
      "filter": [ 
      "lowercase", 
      "edgenGram_filter" 
      ] 
     } 
     } 
    } 
    }, 
    "mappings": { 
    "test": { 
     "properties": { 
     "name": { 
      "type": "string", 
      "fields": { 
      "prefixes": { 
       "type": "string", 
       "analyzer": "edge_ngram_index_analyzer", 
       "search_analyzer": "standard" 
      }, 
      "substrings": { 
       "type": "string", 
       "analyzer": "ngram_index_analyzer", 
       "search_analyzer": "standard" 
      } 
      } 
     } 
     } 
    } 
    } 
} 

그런 다음 쿼리는

POST /sample/test/_search 
{ 
    "query": { 
     "bool": { 
      "minimum_should_match": 1, 
      "should": [ 
       {"match": { "name.substrings": "play" }}, 
       {"match": { "name.prefixes": "magazine" }} 
      ] 
     } 
    } 
} 

주 (name 필드 play을 포함하거나 magazine로 시작하는 모든 문서에 대한 즉, 검색)이 될 것이다 클러스터의 성능을 저하 시키십시오 (more info herehere)

+0

** 업데이트 1 ** 나는 위의 제안을 시도하지만 7 개의 기록을 전부 가져 왔어. 위에서 사용하려고했던 명령을 게시했습니다. –

+0

좋은 캐치. 문제를 일으키는 단어 구분 기호 필터를 제거했습니다. 또한 토크 나이저를 변경합니다. 다시 시도하십시오 – Val

+0

그 덕분에 잘됐다! 대단히 고마워요 –