es查询匹配数组中的所有元素

q3aa0525  于 2021-06-10  发布在  ElasticSearch
关注(0)|答案(1)|浏览(1501)

所以我得到了一个嵌套数组的文档,我想用这个查询过滤它。
我希望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/163873elasticsearch:如何查询精确嵌套数组

55ooxyrt

55ooxyrt1#

首先,如果你按 id: ,你显然不能 id: def 回来。
第二,由于 nested 如果字段被视为单独的子文档,则不能查询所有字段 trips 他们有 changes 等于0——单个行程之间的连接丢失,它们“互不了解”。
您可以使用 inner_hits :

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

然后,最简单的解决方案是动态地将嵌套信息保存在父对象上,如这里所讨论的,并对结果数组使用range/term查询。
编辑:
下面是如何使用 copy_to 进入医生的顶层:

PUT trips_solutions
{
  "mappings": {
    "properties": {
      "trips_changes": {
        "type": "integer"
      },
      "trips": {
        "type": "nested",
        "properties": {
          "changes": {
            "type": "integer",
            "copy_to": "trips_changes"
          }
        }
      }
    }
  }
}
``` `trips_changes` 将是一个数字数组--我假定它们是整数,但有更多类型可用。
然后同步几个文档:

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` 在累积的顶层更改中,拒绝那些适用的更改。

相关问题