我使用nGram分析器(仅发出三元语法)对一些数据编制了索引,以解决compound words problem exactly as described at the ES guide。
但是,这无法正常工作:匹配查询将返回所有至少匹配一个nGram token (每个单词)的文档。
例:
让我们使用该nGram分析器将这两个索引文档放在一个字段中:
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)
这就是第二个文档匹配的原因(它包含“some”和“search”)。它甚至可以将文档与包含 token “som”和“rch”的单词进行匹配。
我真正想要的是一个查询,其中每个分析的 token 必须与匹配(在最佳情况下取决于最小应该匹配),所以是这样的:
"match": {
"content": {
"query": "awe wes eso ome sea ear arc rch",
"analyzer": "whitespace",
"minimum_should_match": "100%"
}
}
..没有实际“手动创建”该查询/在客户端进行预分析。
可以在https://pastebin.com/97QxfaSb中找到用于重现该行为的所有设置和数据。
有这种可能性吗?
最佳答案
在写问题时,我无意中找到了答案:
如果ngram分析器使用ngram过滤器生成三字组(如本指南中所述),则其工作方式如上所述。 (我猜是因为实际标记不是单个ngram而是所有创建的ngram的组合)
为了实现所需的行为,分析器必须使用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"
}
}
在查询该字段时,使用这种方式产生 token 将得到期望的结果。
关于elasticsearch - 查询elasticsearch以使所有分析的ngram token 都匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50370807/