2017-01-13 208 views
0

我有这样的结果删除项目

{ 
    "_index": "products-1479727033119", 
    "_type": "product", 
    "_id": "123", 
    "_score": 5.2519913, 
    "_source": { 
     "name": "Samsung S7", 
     "rating": 4.5123123, 
     "id": "609126", 
     "stores": [ 
     { 
      "id" :123214, 
      "name":"Walmart" 
     }, 
     { 
      "id" :2141251, 
      "name":"ebay" 
     } 
     ], 
    } 
    } 

在某些情况下,我需要我的结果是一样的,但是我需要过滤数组项

而结果应该是这样的:

{ 
    "_index": "products-1479727033119", 
    "_type": "product", 
    "_id": "123", 
    "_score": 5.2519913, 
    "_source": { 
     "name": "Samsung S7", 
     "rating": 4.5123123, 
     "id": "609126", 
     "stores": [ 
     { 
      "id" :123214, 
      "name":"Walmart" 
     } 
     ], 
    } 
    } 

这是可能在一个单一的查询?

回答

0

是的,您必须查看elasticsearch中的嵌套对象。您必须在嵌套对象的模式中定义映射。一旦您将模式设置为支持源文档中的嵌套对象,就可以使用嵌套过滤器innerhits。

对文档使用以下模式映射。现在

-XPut "localhost:9200/products/product/_mapping" 
    { 
     "product": { 
      "_source": { 
       "enabled": true 
      }, 
      "properties": { 
       "stores": { 
        "type": "nested", 
        "properties": { 
         "id": { 
          "type": "string", 
          "index": "analyzed" 
         }, 
         "name": { 
          "type": "string", 
          "index": "analyzed" 
         } 
        } 
       }, 
       "name": { 
        "type": "string", 
        "index": "analyzed" 
       }, 

       "rating": { 
        "type": "integer" 
       }, 
       "id": { 
        "type": "integer" 
       } 
      } 
     } 
    } 

您的用例可以或maynot包括过滤父文档,但因为你基本上是需要过滤嵌套文件相匹配的一些标准,你可以使用嵌套过滤器/带innerhits查询。 elasticsearch中的innerhits返回一个文档中的内嵌套文档与您的嵌套查询匹配。

让我们假设两个情况下─

a)不过滤父文档 -

{ 
    "query": { 
     "filtered": { 
      "query": { 
       "bool": { 
        "must": [{ 
         "nested": { 
          "path": "stores", 
          "query": { 
           "filtered": { 
            "query": { 
             "bool": { 
              "must": [{ 
               "term": { 
                "stores.name": { 
                 "value": "nokia" 
                } 
               } 
              }] 
             } 
            } 
           } 
          }, 
          "inner_hits":{} 
         } 
        }] 
       } 
      } 
     } 
    } 
} 

b)中筛选既为亲和嵌套对象 -

{ 
    "query": { 
     "filtered": { 
      "query": { 
       "bool": { 
        "must": [ 
         {"term": { 
         "name": { 
          "value": "samsung" 
         } 
         }}, 
         { 
         "nested": { 
          "path": "stores", 
          "query": { 
           "filtered": { 
            "query": { 
             "bool": { 
              "must": [{ 
               "term": { 
                "stores.name": { 
                 "value": "nokia" 
                } 
               } 
              }] 
             } 
            } 
           } 
          }, 
          "inner_hits":{} 
         } 
        }] 
       } 
      } 
     } 
    } 
} 

在情况b中,可以在父文档上也有一个过滤器。

Innerhits响应 -

{ 
    "took": 6, 
    "timed_out": false, 
    "_shards": { 
    "total": 5, 
    "successful": 5, 
    "failed": 0 
    }, 
    "hits": { 
    "total": 1, 
    "max_score": 2.122635, 
    "hits": [ 
     { 
     "_index": "nested", 
     "_type": "product", 
     "_id": "AVmYrzR0isULrG9L5jlr", 
     "_score": 2.122635, 
     "_source": { 
      "name": "Samsung S7", 
      "rating": 4.5123123, 
      "id": "609126", 
      "stores": [ 
      { 
       "id": 123214, 
       "name": "Walmart" 
      }, 
      { 
       "id": 898989, 
       "name": "nokia" 
      }, 
      { 
       "id": 67676, 
       "name": "nokia" 
      } 
      ] 
     }, 
     "inner_hits": { 
      "stores": { 
      "hits": { 
       "total": 2, 
       "max_score": 1.8472979, 
       "hits": [ 
       { 
        "_index": "nested", 
        "_type": "product", 
        "_id": "AVmYrzR0isULrG9L5jlr", 
        "_nested": { 
        "field": "stores", 
        "offset": 2 
        }, 
        "_score": 1.8472979, 
        "_source": { 
        "id": 67676, 
        "name": "nokia" 
        } 
       }, 
       { 
        "_index": "nested", 
        "_type": "product", 
        "_id": "AVmYrzR0isULrG9L5jlr", 
        "_nested": { 
        "field": "stores", 
        "offset": 1 
        }, 
        "_score": 1.8472979, 
        "_source": { 
        "id": 898989, 
        "name": "nokia" 
        } 
       } 
       ] 
      } 
      } 
     } 
     } 
    ] 
    } 
} 

正如你可以在响应对象看到,inner_hits出来的附加JSON对象与源文档一起,innerhits JSON对象包含匹配的“所有过滤嵌套文件的阵列诺基亚“作为名称。

你确实得到了你所要求的形式,但采用了不同的格式/数据结构。您可以稍后编写API层翻译器,模型序列化程序将响应解析为您希望客户端(浏览器/应用程序)要求的正确格式。

请参阅elastic innerhits doc以获取更多参考。

希望这会有所帮助 谢谢