【问题标题】:Elasticsearch and the Terms filter AND execution modeElasticsearch 和术语过滤器 AND 执行模式
【发布时间】:2015-12-16 03:48:00
【问题描述】:

我对如何实现过滤后的查询感到困惑,该查询与“所有”提供的术语相匹配,而不是“任何”,基本上是“和”与“或”。

鉴于我有(一个非常简化的版本)一个文件:

{
    "content": {
        "tags": [
            {
                "tag": "Express",
                "type": "other"
            },
            {
                "tag": "Baking",
                "type": "other"
            }
        ]
    }
}

目前我有以下搜索:

{
    "min_score": 0.5,
    "query": {
        "filtered": {
            "query": {},
            "filter": {
                "bool": {
                    "must": [{
                        "nested": {
                            "path": "content.tags",
                            "filter": {
                                "terms": {
                                    "content.tags.tag": ["Express", "Baking"],
                                }
                            }
                        }
                    }],
                    "should": []
                }
            }
        }
    },
    "sort": ["_score"],
    "from": 0,
    "size": 12
}

我知道这将查找任何具有“Express”的文档,并添加到任何具有“Baking”的文档。我需要的是一个过滤器,它只匹配同时存在两个标签的文档。

我已阅读文档,我对它们的理解是我需要将"execution": "and" 添加到过滤器中

{
    "min_score": 0.5,
    "query": {
        "filtered": {
            "query": {},
            "filter": {
                "bool": {
                    "must": [{
                        "nested": {
                            "path": "content.tags",
                            "filter": {
                                "terms": {
                                    "content.tags.tag": ["Express", "Baking"],
                                    "execution": "and"
                                }
                            }
                        }
                    }],
                    "should": []
                }
            }
        }
    },
    "sort": ["_score"],
    "from": 0,
    "size": 12
}

遗憾的是,这匹配 0 个文档,而我知道其中有 28 个。

我的content.tags.tag 字段没有被分析,而content.tags 有很多嵌套对象,如上所述,所以我理解它的意思是它必须包含每个标签之一,但似乎并非如此。

有谁知道我是怎么做到的?

【问题讨论】:

  • 我还要提一下,这里我把查询的主体留空了,我只关心这个问题中的过滤器。我有其他查询部分没有反映该问题,并且按预期工作。
  • 你用的是什么版本的ES? 2.0 忽略执行选项(见elastic.co/guide/en/elasticsearch/reference/current/…
  • 嗨,我还在 1.7 上,因为它是生产服务器,在这方面很幸运。

标签: elasticsearch


【解决方案1】:

您要求的是一个包含术语"Express""Baking" 的嵌套文档,它与您列出的(父)文档不匹配。它有一个匹配第一个术语的嵌套文档,和另一个匹配第二个术语的嵌套文档,但没有匹配两者的嵌套文档。正如@Frederick 指出的那样,您的第二个查询无论如何都不会在 Es 2.0 中工作。

另一方面,当我尝试您的查询时,无论如何我都没有得到任何结果,因为您的空查询子句不匹配任何内容。但是,当我删除它时,文档被退回,与其中任何一个条款匹配但不是两者都匹配的文档也是如此。 (如果 "execution": "and" 没有被忽略,它将不会返回任何文档)。

无论如何,听起来这就是您所要求的:查找包含与两个术语中的每一个匹配的嵌套文档的父文档:

POST /test_index/_search
{
   "filter": {
      "bool": {
         "must": [
            {
               "nested": {
                  "path": "content.tags",
                  "filter": {
                     "term": {
                        "content.tags.tag": "Express"
                     }
                  }
               }
            },
            {
               "nested": {
                  "path": "content.tags",
                  "filter": {
                     "term": {
                        "content.tags.tag": "Baking"
                     }
                  }
               }
            }
         ]
      }
   }
}

这是我用来测试所有这些的一些代码(在 ES 2.1 中):

http://sense.qbox.io/gist/e375721509acbb5170e07eb969ea4409921f42d3

【讨论】:

  • 我只清空了我在评论中提到的示例的查询子句。不过感谢您的回复,我不敢相信我必须为每个术语创建一个单独的过滤器,因为实际上最多可能有 20 个 :(
【解决方案2】:

使用两个不同的必须条件,

{
    "min_score": 0.5,
    "query": {
        "filtered": {
            "query": {},
            "filter": {
                "bool": {
                    "must": [{
                        "nested": {
                            "path": "content.tags",
                            "filter": {
                                "terms": {
                                    "content.tags.tag": "Banking"
                                }
                            }
                        }
                    },"nested": {
                            "path": "content.tags",
                            "filter": {
                                "terms": {
                                    "content.tags.tag": "Express"
                                }
                            }
                        }
                    }],
                    "should": []
                }
            }
        }
    },
    "sort": ["_score"],
    "from": 0,
    "size": 12
}

【讨论】:

  • 我选择了另一个回复,因为它有解释,但非常感谢回复:D
  • 我相信他的更好,只是我们同时发送。即使我投票支持他的答案:)
猜你喜欢
  • 1970-01-01
  • 2013-11-13
  • 2014-07-31
  • 1970-01-01
  • 2015-08-02
  • 2020-07-07
  • 1970-01-01
  • 2018-02-17
  • 1970-01-01
相关资源
最近更新 更多