【问题标题】:ES query to match all elements in arrayES查询匹配数组中的所有元素
【发布时间】:2021-01-15 02:45:44
【问题描述】:

所以我得到了这份文件 我想用这个查询过滤的嵌套数组。

我希望 ES 返回所有项目都具有更改 = 0 的所有文档,并且仅此而已。 如果文档在列表中甚至有一个更改为 1 的项目,则将其丢弃。

有什么方法可以从我已经编写的查询开始实现这一点?还是应该改用脚本?

文件:

{
    "id": "abc",
    "_source" : {
        "trips" : [
            {
                "type" : "home",
                "changes" : 0
            },
            {
                "type" : "home",
                "changes" : 1
            }
        ]
    }
},
{
        "id": "def",
        "_source" : {
            "trips" : [
                {
                    "type" : "home",
                    "changes" : 0
                },
                {
                    "type" : "home",
                    "changes" : 0
                }
            ]
        }
    }

查询:

GET trips_solutions/_search

    {
      "query": {
        "bool": {
          "must": [
            {
              "term": {
                "id": {
                  "value": "abc"
                }
              }
            },
            {
              "nested": {
                "path": "trips",
                "query": {
                  "range": {
                    "trips.changes": {
                      "gt": -1,
                      "lt": 1
                    }
                  }
                }
              }
            }
          ]
        }
      }
    }

预期结果:

{
            "id": "def",
            "_source" : {
                "trips" : [
                    {
                        "type" : "home",
                        "changes" : 0
                    },
                    {
                        "type" : "home",
                        "changes" : 0
                    }
                ]
            }
        }

Elasticsearch 版本:7.6.2

已经阅读了这个答案,但他们没有帮助我: https://discuss.elastic.co/t/how-to-match-all-item-in-nested-array/163873 ElasticSearch: How to query exact nested array

【问题讨论】:

    标签: elasticsearch kibana elastic-stack kibana-7


    【解决方案1】:

    首先,如果您按id: abc 过滤,您显然将无法返回id: def

    其次,由于 nested 字段被视为单独的子文档的性质,您无法查询所有 tripschanges 等于 0 - 各个行程之间的连接丢失并且它们“彼此不了解”。

    可以做的就是只返回与您使用inner_hits 的嵌套查询匹配的行程:

    GET trips_solutions/_search
    {
      "_source": "false",
      "query": {
        "bool": {
          "must": [
            {
              "nested": {
                "inner_hits": {},
                "path": "trips",
                "query": {
                  "term": {
                    "trips.changes": {
                      "value": 0
                    }
                  }
                }
              }
            }
          ]
        }
      }
    }
    

    最简单的解决方案是将此嵌套信息动态保存在父对象 like discussed here 上,并对结果数组使用范围/术语查询。


    编辑:

    以下是在文档顶层使用copy_to 的方法:

    PUT trips_solutions
    {
      "mappings": {
        "properties": {
          "trips_changes": {
            "type": "integer"
          },
          "trips": {
            "type": "nested",
            "properties": {
              "changes": {
                "type": "integer",
                "copy_to": "trips_changes"
              }
            }
          }
        }
      }
    }
    

    trips_changes 将是一个数字数组——我认为它们是整数,但 more types are available

    然后同步一些文档:

    POST trips_solutions/_doc
    {"trips":[{"type":"home","changes":0},{"type":"home","changes":1}]}
    
    POST trips_solutions/_doc
    {"trips":[{"type":"home","changes":0},{"type":"home","changes":0}]}
    

    最后查询:

    GET trips_solutions/_search
    {
      "query": {
        "bool": {
          "must": [
            {
              "nested": {
                "path": "trips",
                "query": {
                  "term": {
                    "trips.changes": {
                      "value": 0
                    }
                  }
                }
              }
            },
            {
              "script": {
                "script": {
                  "source": "doc.trips_changes.stream().filter(val -> val != 0).count() == 0"
                }
              }
            }
          ]
        }
      }
    }
    

    请注意,我们通常首先使用嵌套术语查询进行过滤以缩小搜索范围(脚本很慢,所以这很有用)。然后我们检查累积的顶级更改中是否有任何非零changes 并拒绝那些适用的。

    【讨论】:

    • 感谢您的友好回复!不幸的是,这不是最适合我需求的选择!我需要过滤每个项目,因为数组对我来说就像一个“数据包”,所以如果“数据包”不适合所有条件,我想丢弃文档。你知道脚本是否可以帮助我吗?
    • 更新了我的答案——希望对您有所帮助。
    • 非常感谢乔!你真是太好了!
    • 没有问题!随意接受并投票赞成答案;)
    猜你喜欢
    • 2023-03-04
    • 1970-01-01
    • 2013-08-10
    • 1970-01-01
    • 2013-11-12
    • 2020-06-19
    • 1970-01-01
    • 2015-12-23
    • 2012-05-30
    相关资源
    最近更新 更多