繁体   English   中英

使用过滤器数组字段查询

[英]Query with filter array field

我想返回仅包含一些数组字段成员的文档。
例如,我有两个订单文件:\

{   
    "orderNumber":"ORD-111",
    "items":[{"name":"part-1","status":"new"},
             {"name":"part-2","status":"paid"}]
}
{
    "orderNumber":"ORD-112",
    "items":[{"name":"part-3","status":"paid"},
             {"name":"part-4","status":"supplied"}]
}

我想创建一个查询,以便我的结果将包括所有订单文档,但仅包含与 {"status":"supplied"} 匹配的项目。
结果应如下所示:\

{   
    "orderNumber":"ORD-111",
    "items":[]
}
{
    "orderNumber":"ORD-112",
    "items":[{"name":"part-4","status":"supplied"}]
}

您可以使用嵌套查询inner_hits在结果中仅获取匹配的数组值

添加一个工作示例

索引映射:

{
  "mappings": {
    "properties": {
      "items": {
        "type": "nested"
      }
    }
  }
}

搜索查询:

{
  "query": {
    "nested": {
      "path": "items",
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "items.status": "supplied"
              }
            }
          ]
        }
      },
      "inner_hits": {}
    }
  }
}

搜索结果:

"hits": [
      {
        "_index": "67890614",
        "_type": "_doc",
        "_id": "2",
        "_score": 1.2039728,
        "_source": {
          "orderNumber": "ORD-112",
          "items": [
            {
              "name": "part-3",
              "status": "paid"
            },
            {
              "name": "part-4",
              "status": "supplied"
            }
          ]
        },
        "inner_hits": {
          "items": {
            "hits": {
              "total": {
                "value": 1,
                "relation": "eq"
              },
              "max_score": 1.2039728,
              "hits": [
                {
                  "_index": "67890614",
                  "_type": "_doc",
                  "_id": "2",
                  "_nested": {
                    "field": "items",
                    "offset": 1
                  },
                  "_score": 1.2039728,
                  "_source": {
                    "name": "part-4",
                    "status": "supplied"      // note this
                  }
                }
              ]
            }
          }
        }
      }
    ]

Elasticsearch 使匹配字段变平,因此无法分辨数组中匹配的实际元素。

如前所述,您可以使用嵌套查询。

对象的 arrays 如何展平 Elasticsearch 没有内部对象的概念。 因此,它将 object 层次结构扁平化为字段名称和值的简单列表。 例如,考虑以下文档:

PUT my-index-000001/_doc/1
{
  "group" : "fans",
  "user" : [ 
    {
      "first" : "John",
      "last" :  "Smith"
    },
    {
      "first" : "Alice",
      "last" :  "White"
    }
  ]
}

用户字段作为 object 类型的字段动态添加。

之前的文档将在内部转换为看起来更像这样的文档:

{
  "group" :        "fans",
  "user.first" : [ "alice", "john" ],
  "user.last" :  [ "smith", "white" ]
}

user.first 和 user.last 字段被扁平化为多值字段,失去了 alice 和 white 的关联。 该文档将错误地匹配对 alice AND smith 的查询:

GET my-index-000001/_search
{
  "query": {
    "bool": {
      "must": [
        { "match": { "user.first": "Alice" }},
        { "match": { "user.last":  "Smith" }}
      ]
    }
  }
}
 

要回答您的问题:

如果需要索引对象的 arrays 并保持数组中每个 object 的独立性,请使用嵌套数据类型而不是 object 数据类型。

在内部,嵌套对象将数组中的每个 object 索引为单独的隐藏文档,这意味着每个嵌套的 object 都可以使用嵌套查询独立于其他对象进行查询:

PUT my-index-000001
{
  "mappings": {
    "properties": {
      "user": {
        "type": "nested" 
      }
    }
  }
}

PUT my-index-000001/_doc/1
{
  "group" : "fans",
  "user" : [
    {
      "first" : "John",
      "last" :  "Smith"
    },
    {
      "first" : "Alice",
      "last" :  "White"
    }
  ]
}

GET my-index-000001/_search
{
  "query": {
    "nested": {
      "path": "user",
      "query": {
        "bool": {
          "must": [
            { "match": { "user.first": "Alice" }},
            { "match": { "user.last":  "Smith" }} 
          ]
        }
      }
    }
  }
}

GET my-index-000001/_search
{
  "query": {
    "nested": {
      "path": "user",
      "query": {
        "bool": {
          "must": [
            { "match": { "user.first": "Alice" }},
            { "match": { "user.last":  "White" }} 
          ]
        }
      },
      "inner_hits": { 
        "highlight": {
          "fields": {
            "user.first": {}
          }
        }
      }
    }
  }
}

用户字段映射为嵌套类型,而不是类型 object。

此查询不匹配,因为 Alice 和 Smith 不在同一个嵌套 object 中。

此查询匹配,因为 Alice 和 White 在同一个嵌套 object 中。

inner_hits 允许我们突出显示匹配的嵌套文档。

与嵌套文档交互嵌套文档可以是:

使用嵌套查询进行查询。 使用嵌套和 reverse_nested 聚合进行分析。 使用嵌套排序进行排序。 用嵌套的内部匹配检索和突出显示。 因为嵌套文档被索引为单独的文档,所以它们只能在嵌套查询的 scope、nested/reverse_nested 聚合或嵌套内部命中的范围内访问。

采用这种方法时要考虑性能,因为它的成本要高得多。

更多细节

您可以查看来源: https://www.elastic.co/guide/en/elasticsearch/reference/current/nested.html

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM