Elasticsearch 嵌套过滤器包含与排除

2023-12-01

我有一个使用嵌套对象的对象映射(props在我们的示例中)以类似标签的方式。 每个标签可以属于一个客户/用户,当我们希望允许我们的用户生成query_string风格搜索针对props.name.

问题是,当我们运行查询时,一个对象是否有多个 props,并且如果多个 props 之一与过滤器匹配,而其他 props 不匹配,则返回该对象,而当我们想要相反的情况时 - 如果一个返回 false,则不返回 vs.如果返回true则返回。

我在这里发布了一个综合示例:https://gist.github.com/d2kagw/1c9d4ef486b7a2450d95

提前致谢。


我相信在这里您可能需要利用扁平值列表的优势,例如值数组。数组和嵌套对象之间的主要区别在于,后者“知道”嵌套属性的哪个值对应于数组中另一个属性的另一个值。same嵌套对象。另一方面,值数组会使某个属性的值变平,并且您会失去属性之间的“关联”client_id and a name。意思是,对于数组你有props.client_id = [null, 2] and props.name = ["petlover", "premiumshopper"].

和你的nested您想要将该字符串与所有值匹配的过滤器props.name意义ALL nested props.name一位父文档的 s 需要匹配。嗯,嵌套对象不会发生这种情况,因为嵌套文档是独立的并且是单独查询的。并且,如果至少一个嵌套文档匹配,则将其视为匹配。

换句话说,对于像这样的查询"query": "props.name:(carlover NOT petlover)"您基本上需要针对扁平化的值列表运行它,就像数组一样。您需要针对 ["carlover", "petlover"] 运行该查询。

我给你的建议是制作嵌套文档"include_in_parent": true(意思是,在父级中保留一个扁平的、类似数组的值列表)并稍微更改一下查询:

  • for the query_string部分,使用扁平属性方法能够匹配元素组合列表的查询,而不是逐个元素。
  • for the match (or term,见下文)和missing部件使用嵌套属性方法,因为您可以有null在那里。 Amissing仅当整个数组丢失而不是其中缺少一个值时,数组上的内容才会匹配,因此这里不能使用与查询相同的方法,其中值在数组中被展平。
  • 可选,但对于query match我会使用的整数term,因为它不是字符串而是整数,并且默认情况下是not_analyzed.

话虽这么说,经过上述更改,这些更改是:

{
  "mappings" : {
    ...
        "props": {
          "type": "nested",
          "include_in_parent": true,
   ...
  1. 应该(并且确实)返回零结果
GET /nesting-test/_search?pretty=true
{
  "query": {
    "filtered": {
      "filter": {
        "and": [
          {
            "query": {
              "query_string": { "query": "props.name:((carlover AND premiumshopper) NOT petlover)" }
            }
          },
          {
            "nested": {
              "path": "props",
              "filter": {
                "or": [ { "query": { "match": { "props.client_id": 1 } } }, { "missing": { "field": "props.client_id" } } ]
              }
            }
          }
        ]
      }
    }
  }
}
  1. 应该(并且确实)只返回 1
GET /nesting-test/_search?pretty=true
{
  "query": {
    "filtered": {
      "filter": {
        "and": [
          {"query": {"query_string": { "query": "props.name:(carlover NOT petlover)" } } },
          {
            "nested": {
              "path": "props",
              "filter": {
                "or": [{ "query": { "match": { "props.client_id": 1 } } },{ "missing": { "field": "props.client_id" } } ]
              }
            }
          }
        ]
      }
    }
  }
}
  1. 应该(并且确实)只返回 2
GET /nesting-test/_search?pretty=true
{
  "query": {
    "filtered": {
      "filter": {
        "and": [
          { "query": {"query_string": { "query": "props.name:(* NOT carlover)" } } },
          {
            "nested": {
              "path": "props",
              "filter": {
                "or": [{ "query": { "term": { "props.client_id": 1 } } },{ "missing": { "field": "props.client_id" } }
                ]
              }
            }
          }
        ]
      }
    }
  }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Elasticsearch 嵌套过滤器包含与排除 的相关文章

随机推荐