2017-04-16 3 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*" 
     } 
    } 
} 

アップデート1 私はすべてのサンプルの後にテストを使用するステートメントを作成、更新:

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

私は、それらに代わりにワイルドカードをやって「再生」という言葉を持っていた唯一の名前を返すために、次のコマンドを実行しましたサーチ。これは正しく動作し、2つのレコードしか返しませんでした。

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

"magazine"で始まる名前だけを返すために、次のコマンドを実行しました。私の期待は、「オンラインマガジン」、「ベストマガジン」、「雑誌の友人」は出現しないということでした。しかし、これらの3つを含めて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が必要です。

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で始まるすべての文書を検索)となります。注:それは意志として、部分文字列を検索するためwildcardを使用していません(詳細はherehere

+0

**アップデート1 **私は上記の提案をしようとしたが、I 7つのレコードをすべて戻しました。私は上記で使用しようとしたコマンドを投稿しました。 –

+0

良いキャッチ。私は問題を引き起こしていたword delimiter filterを削除しました。また、tokenizerを変更しました。もう一度やり直してください – Val

+0

うまくいった!ありがとうございました –

関連する問題