2017-04-16 88 views
1

我想索引字符串包含連字符但不包含空格,句點或任何其他標點符號。我不想根據連字符分割單詞,而是希望將連字符作爲索引文本的一部分。Elasticsearch自定義分析器與Ngram和沒有字母分隔符連字符

例如,我的6個文本字符串將是:

  • magazineplayon
  • magazineofhorses
  • 在線雜誌
  • 最好的雜誌
  • 朋友-的-雜誌
  • magazineplaygames

我希望能夠搜索包含「play」的文本或文本以「magazine」開頭的文本。

我已經能夠使用ngram使包含「play」的文本正常工作。但是,連字符會導致文本分裂,並且包含連字符後面的單詞中包含「雜誌」的結果。我只想從字符串的開頭開始以「magazine」出現的單詞。

基於以上的樣品,只有 「雜誌」 剛開始的時候,這些3應該出現:

  • magazineplayon
  • magazineofhorses
  • magazineplaygames

請與我ElasticSearch指數樣本幫助:

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*" 
     } 
    } 
} 

更新1 我更新了我所有的創建語句中使用測試樣品後:

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

然後我跑到下面的命令只返回了其中的一句話「玩」,而不是做通配符名搜索。這工作正常,並返回只有兩個記錄。

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

我運行以下命令,僅返回以「magazine」開頭的名稱。我的期望是「網絡雜誌」,「最佳雜誌」和「雜誌朋友」不會出現。但是,所有七條記錄都被返回,包括這三條。

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來檢查字段「以」開始「某個標記。

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字段包含playmagazine開頭的所有文件,搜索):不用於搜索字符串使用wildcard,因爲它會殺死你的集羣的性能(更多信息herehere

+0

更新1 **我嘗試了上述建議,但我把所有7條記錄都拿回來了我發佈了上面我嘗試使用的命令。 –

+0

好,趕上。我刪除了單詞分隔符過濾器,這是導致問題,我也改變了標記器。請再試一次 – Val

+0

這很棒!非常感謝 –