Eke*_*ein 5 arrays term elasticsearch
我有如下文件:
{
"tags" => [
"tag1",
"tag2",
],
"name" => "Example 1"
}
{
"tags" => [
"tag1",
"tag3",
"tag4"
],
"name" => "Example 2"
}
Run Code Online (Sandbox Code Playgroud)
我现在想要的是进行术语搜索,其中给定的数组可能如下所示:
[tag1, tag3]
Run Code Online (Sandbox Code Playgroud)
预期命中应该是:
{
"tags" => [
"tag1",
"tag3",
"tag4"
],
"name" => "Example 2"
}
Run Code Online (Sandbox Code Playgroud)
但是,当我执行以下查询时:
GET _search
{
"query": {
"filtered": {
"query": {
"match_all": {}
},
"filter": {
"bool": {
"must": [
{
"terms": {
"tags": [
"tag1",
"tag3"
]
}
}
]
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
因为示例 1 和示例 2 都包含 tag1 或 tag3,所以我得到了“示例 1”和“示例 2”作为命中。通过查看条款的文档,我发现条款实际上是一个包含查询。
在这种情况下,我如何确保示例 2 是使用 tag1 和 tag3 进行查询时的唯一命中?
对于那些在 2020 年关注这一点的人来说,您可能已经注意到它minimum_should_match很久以前就已被弃用。
目前有一个替代方案,那就是使用terms_set.
例如:
{
"query": {
"terms_set": {
"programming_languages": {
"terms": [ "c++", "java", "php" ],
"minimum_should_match_field": "required_matches"
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
上面的示例假设required_matches存在一个包含整数的字段,该整数定义了应该有多少个匹配项。
更有用的是替代字段minimum_should_match_script。
请参阅下面的示例:
{
"query": {
"terms_set": {
"programming_languages": {
"terms": [ "c++", "java", "php" ],
"minimum_should_match_script": {
"source": "2"
},
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
您始终可以使用上下文内部filter来使其成为过滤器。
在这里阅读更多内容
您需要通过添加到过滤器来将执行模式设置为“and”,以便所有术语都必须包含在文档中才能被视为匹配"execution": "and"terms
GET _search
{
"query": {
"filtered": {
"query": {
"match_all": {}
},
"filter": {
"terms": {
"tags": [
"tag1",
"tag3"
],
"execution": "and"
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
这实际上与使用所有项的结合构建过滤器相同bool must,但形式更紧凑。