elasticsearch 查询elasticsearch以使所有分析的ngram令牌匹配
我用一个nGram分析仪(它只发出三克)对一些数据进行了索引,以解决这个问题 然而,这并没有像预期的那样起作用:相应的匹配查询将返回至少有一个nGram标记(每个单词)匹配的所有文档 例如: 让我们使用nGram分析器,使用单个字段获取这两个索引文档:elasticsearch 查询elasticsearch以使所有分析的ngram令牌匹配,elasticsearch,tokenize,n-gram,elasticsearch,Tokenize,N Gram,我用一个nGram分析仪(它只发出三克)对一些数据进行了索引,以解决这个问题 然而,这并没有像预期的那样起作用:相应的匹配查询将返回至少有一个nGram标记(每个单词)匹配的所有文档 例如: 让我们使用nGram分析器,使用单个字段获取这两个索引文档: POST /compound_test/doc/_bulk { "index": { "_id": 1 }} { "content": "elasticsearch is awesome" } { "index": { "_id": 2 }} {
POST /compound_test/doc/_bulk
{ "index": { "_id": 1 }}
{ "content": "elasticsearch is awesome" }
{ "index": { "_id": 2 }}
{ "content": "some search queries don't perform good" }
现在,如果我运行以下查询,我将得到两个结果:
"match": {
"content": {
"query": "awesome search",
"minimum_should_match": "100%"
}
}
由此构造的查询可以表示为:
(awe OR wes OR eso OR ome) AND (sea OR ear OR arc OR rch)
"match": {
"content": {
"query": "awe wes eso ome sea ear arc rch",
"analyzer": "whitespace",
"minimum_should_match": "100%"
}
}
这就是第二个文档匹配的原因(它包含“some”和“search”)。它甚至可以将文档与包含标记“som”和“rch”的单词进行匹配
我实际上想要的是一个查询,其中每个分析的标记必须匹配(在最佳情况下,取决于最小值应该匹配),因此类似这样:
(awe OR wes OR eso OR ome) AND (sea OR ear OR arc OR rch)
"match": {
"content": {
"query": "awe wes eso ome sea ear arc rch",
"analyzer": "whitespace",
"minimum_should_match": "100%"
}
}
…而不是“直接”创建该查询/在客户端对其进行预分析
可在以下位置找到再现该行为的所有设置和数据:
有这种可能性吗?在写问题时,我意外地找到了答案: 如果ngram分析仪使用ngram过滤器生成三叉图(如指南中所述),则其工作方式如上所述。(我猜是因为实际的令牌不是单个ngrams,而是所有创建的ngrams的组合) 为实现所需的行为,分析仪必须使用ngram标记器:
"tokenizer": {
"trigram_tokenizer": {
"type": "ngram",
"min_gram": 3,
"max_gram": 3,
"token_chars": [
"letter",
"digit"
]
}
},
"analyzer": {
"trigrams_with_tokenizer": {
"type": "custom",
"tokenizer": "trigram_tokenizer"
}
}
使用这种方式生成令牌将在对该字段进行查询时产生预期结果。在编写问题时,我意外地找到了答案: 如果ngram分析仪使用ngram过滤器生成三叉图(如指南中所述),则其工作方式如上所述。(我猜是因为实际的令牌不是单个ngrams,而是所有创建的ngrams的组合) 为实现所需的行为,分析仪必须使用ngram标记器:
"tokenizer": {
"trigram_tokenizer": {
"type": "ngram",
"min_gram": 3,
"max_gram": 3,
"token_chars": [
"letter",
"digit"
]
}
},
"analyzer": {
"trigrams_with_tokenizer": {
"type": "custom",
"tokenizer": "trigram_tokenizer"
}
}
使用这种方法生成令牌将在查询该字段时产生预期结果。是的,我正打算指出这个问题,即您应该使用ngram令牌生成器而不是ngram令牌筛选器,因为您的示例与ES指南中的示例不同(示例显示了复合词,而您的示例没有任何复合词). 很高兴你明白了!我猜“elasticsearch”是一个复合词……)好吧,我想用英语保留这个例子。。顺便说一句,ngram也可以很好地处理小的打字错误。是的,我要指出的正是这个问题,即你应该使用ngram标记器而不是ngram标记过滤器,因为你的示例与ES指南中的示例不同(示例显示了复合词,而你的示例没有)。很高兴你明白了!我猜“elasticsearch”是一个复合词……)好吧,我想用英语保留这个例子。。顺便说一句,Ngram也很有可能处理小的打字错误。