包含空白的 Elasticsearch nGram 搜索查询



>我创建了以下索引:

{  
"settings":{  
      "number_of_shards":1,
      "number_of_replicas":0,
      "blocks":{  
         "read_only_allow_delete":false,
         "read_only":false
      },
      "analysis":{  
         "filter":{  
            "autocomplete_filter":{  
               "type":"ngram",
               "min_gram":3,
               "max_gram":30
            }
         },
         "analyzer":{  
            "autocomplete":{  
               "type":"custom",
               "tokenizer":"standard",
               "filter":[  
                  "lowercase",
                  "autocomplete_filter"
               ]
            }
         }
      }
   },
   "mappings":{  
      "movie":{  
         "properties":{  
            "title":{  
               "type":"text"
            },
            "actors":{  
               "type":"nested",
               "include_in_all":true,
               "properties":{  
                  "name":{  
                     "type":"text",
                     "analyzer":"autocomplete",
                     "search_analyzer": "standard"
                  },
                  "age":{  
                     "type":"long",
                     "index":"false"
                  }
               }
            }
         }
      }
   }
}

我已经通过端点插入了以下数据_bulk:

{"index":{"_index":"movies","_type":"movie","_id":1}}
{"title":"Ocean's 11", "actors":[{"name":"Brad Pitt","age":54}, {"name":"George Clooney","age":56}, {"name":"Julia Roberts","age":50}, {"name":"Andy Garcia","age":61}]}
{"index":{"_index":"movies","_type":"movie","_id":2}}
{"title":"Usual suspects", "actors":[{"name":"Kevin Spacey","age":58}, {"name":"Benicio del Toro","age":50}]}
{"index":{"_index":"movies","_type":"movie","_id":3}}
{"title":"Fight club", "actors":[{"name":"Brad Pitt","age":54}, {"name":"Edward Norton","age":48}, {"name":"Helena Bonham Carter","age":51}, {"name":"Jared Leto","age":46}]}
{"index":{"_index":"movies","_type":"movie","_id":24}
{"title":"Fight club", "actors":[{"name":"Brad Garrett","age":57}, {"name":"Ben Stiller","age":52}, {"name":"Robin Williams","age":63}]}

现在我想按演员名称搜索索引。例如,当我搜索布拉德时,我得到所有电影都有一个名叫布拉德的演员,这很好。

但是当我搜索rad p时,我只想要布拉德皮特的电影,而不是布拉德加勒特,但我得到了布拉德加勒特。这是我的搜索查询:

{  
   "query":{  
      "nested":{  
         "path":"actors",
         "query":{  
            "match":{  
               "actors.name":{  
                  "query":"rad p",
                  "analyzer":"standard"
               }
            }
         },
         "inner_hits":{  
         }
      }
   }
}

我正在调用的终结点是

/电影/

电影/_search漂亮

我的问题是,如何正确实现上述功能?

谢谢

顺便说一句,弹性搜索版本是6.1.0。

这是因为standard分词器会根据空格和标点符号将输入拆分为标记,因此Brad Pitt变得bradpitt,因此您将没有带有rad p的令牌。

您需要做的是将分词器更改为(例如(keyword,以便您将完整的输入视为一个标记,然后可以对其应用 ngram。

或者更简单的是,您可以简单地使用 ngram 分词器而不是分词过滤器

正如 Val 所说,您必须使用 nGram 标记器来执行此操作,我还必须将搜索查询更改为:

{ "query":{ "nested":{ "path":"searchable", "query":{ "bool":{ "must":{ "match":{ "searchable.searchKeyword":{ "query":"%1$s" } } } } }, "inner_hits":{ } } } }

我使用 nGram 分词器的新索引:

{
"number_of_shards":1, "number_of_replicas":0, "blocks":{
"read_only_allow_delete":false, "read_only":false }, "analysis":{
"analyzer":{
"autocomplete":{
"tokenizer":"search_tokenizer", "filter":[
"lowercase", "asciifolding" ] } }, "tokenizer":{
"search_tokenizer":{
"type":"ngram", "token_chars":[
"letter", "digit", "whitespace", "punctuation", "symbol" ], "min_gram":3, "max_gram":30 } } } }

最新更新