在Elasticsearch中,如何从多层嵌套对象中的多个字段上搜索字符串

时间:2019-03-27 07:11:16

标签: elasticsearch nested multi-level elasticsearch-6

在Elasticsearch 6中,我的数据带有这样的嵌套对象:

{
    "brands" : 
    [
        {
            "brand_name" : "xyz",
            "products" : 
            [
               {
                   "title" : "test",
                   "mrp" : 100,
                   "sp" : 90,
                   "status" : 1
               },
               {
                   "title" : "test1",
                   "mrp" : 50,
                   "sp" : 45,
                   "status" : 1
                }
            ]
        },
        {
            "brand_name" : "aaa",
            "products" : 
            [
                {
                    "title" : "xyz",
                    "mrp" : 100,
                    "sp" : 90,
                    "status" : 1
                },
                {
                    "title" : "abc",
                    "mrp" : 50,
                    "sp" : 45,
                    "status" : 1
                }
            ]
        }
    ]
}

我想从字段brand_name或字段标题中进行搜索。我想以相同的inner_hits返回所有结果。

例如:如果我将搜索字符串输入为“ xyz”,则应返回两个品牌对象和相应的产品对象。 如果我将搜索字符串输入为“ test”,则它应仅返回只有第一个产品对象的第一个品牌数组。

如何实现这一目标。有什么想法吗?

我已经尝试过像这样的嵌套路径查询:

{
  "query": {
    "bool": {
      "must": [
        {
          "nested": {
            "path": "brands",
            "query": {
              "bool": {
                "should": [
                  {
                    "term": {
                      "brands.brand_name": "xyz"
                    }
                  },
                  {
                    "term": {
                      "brands.brand_name.keyword": "aaa"
                    }
                  },
                  {
                    "nested": {
                      "path": "brands.products",
                      "query": {
                        "bool": {
                          "should": [
                            {
                              "match": {
                                "brands.products.title": "xyz"
                              }
                            }
                          ]
                        }
                      },
                      "inner_hits": {}
                    }
                  }
                ]
              }
            },
            "inner_hits": {}
          }
        }
      ]
    }
  }
}

但是,此查询返回的多个inner_hits响应以及每个品牌和每种产品的多个数组对象。

我希望与字符串匹配的所有品牌名称这样的响应都应在一个数组下列出,而所有产品应在同一inner_hits下在另一个数组下列出。

1 个答案:

答案 0 :(得分:1)

由于您希望根据匹配发生的位置(例如brands.brand_namebrands.products.title来改变内部匹配,因此您可以有两个查询,一个查询品牌名称,另一个查询产品标题,作为独立的嵌套查询。然后,这些查询应放在should查询的bool子句中。每个嵌套查询都应具有自己的inner_hits,如下所示:

{
  "query": {
    "bool": {
      "should": [
        {
          "nested": {
            "path": "brands",
            "inner_hits": {},
            "query": {
              "term": {
                "brands.brand_name.keyword": "test"
              }
            }
          }
        },
        {
          "nested": {
            "path": "brands.products",
            "inner_hits": {},
            "query": {
              "term": {
                "brands.products.title": "test"
              }
            }
          }
        }
      ]
    }
  },
  "_source": false
}