查询 elasticsearch 使所有分析的 ngram 标记匹配
Query elasticsearch to make all analyzed ngram tokens to match
我使用 nGram 分析器(仅发出三元组)对一些数据进行了索引,以解决 compound words problem exactly as described at the ES guide。
然而,这并没有像预期的那样工作:相应的匹配查询将 return 至少匹配一个 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")。它甚至可以匹配包含标记 "som" 和 "rch" 的单词的文档。
我真正想要的是一个查询,其中每个分析的标记必须匹配(在最好的情况下取决于最小应该匹配),所以像这样:
"match": {
"content": {
"query": "awe wes eso ome sea ear arc rch",
"analyzer": "whitespace",
"minimum_should_match": "100%"
}
}
..无需实际创建该查询 "from hand" / 在客户端对其进行预分析。
可以在 https://pastebin.com/97QxfaSb
找到重现该行为的所有设置和数据
有这种可能吗?
在写题的时候,无意中找到了答案:
如果 ngram 分析器使用 ngram-filter 生成 trigrams(如指南中所述),它的工作方式如上所述。 (我猜是因为实际的标记不是单个 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"
}
}
使用这种方式生成标记将在查询该字段时产生预期的结果。
我使用 nGram 分析器(仅发出三元组)对一些数据进行了索引,以解决 compound words problem exactly as described at the ES guide。
然而,这并没有像预期的那样工作:相应的匹配查询将 return 至少匹配一个 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")。它甚至可以匹配包含标记 "som" 和 "rch" 的单词的文档。
我真正想要的是一个查询,其中每个分析的标记必须匹配(在最好的情况下取决于最小应该匹配),所以像这样:
"match": {
"content": {
"query": "awe wes eso ome sea ear arc rch",
"analyzer": "whitespace",
"minimum_should_match": "100%"
}
}
..无需实际创建该查询 "from hand" / 在客户端对其进行预分析。
可以在 https://pastebin.com/97QxfaSb
找到重现该行为的所有设置和数据有这种可能吗?
在写题的时候,无意中找到了答案:
如果 ngram 分析器使用 ngram-filter 生成 trigrams(如指南中所述),它的工作方式如上所述。 (我猜是因为实际的标记不是单个 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"
}
}
使用这种方式生成标记将在查询该字段时产生预期的结果。