簡體   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