[英]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.