【问题标题】:Filter nested objects in elasticsearch query based on query根据查询过滤elasticsearch查询中的嵌套对象
【发布时间】:2016-05-05 19:36:52
【问题描述】:

我有包含多个嵌套文档的文档。嵌套查询工作正常,但即使搜索查询仅匹配少数嵌套对象,它们仍会返回所有嵌套对象(即整个文档)。但是,它确实会过滤整个文档。

这是一个例子:

PUT /demo
{
  "mappings": {
    "company": {
      "properties": {
        "employees": {
          "type": "nested"
        }
      }
    }
  }
}

PUT
/demo/company/1
{
  "id": 1,
  "name": "Google",
  "emp_count": 3,
  "employees": [{
    "id": 1,
    "name": "John",
    "address": {
      "city": "Mountain View",
      "state": "California",
      "country": "United States"
    }
  }]
}

PUT
/demo/company/2
{
  "id": 1,
  "name": "Facebook",
  "emp_count": 3,
  "employees": [{
    "id": 1,
    "name": "Amber",
    "address": {
      "city": "Bangalore",
      "state": "Karnataka",
      "country": "India"
    }
  }, {
    "id": 1,
    "name": "Adrian",
    "address": {
      "city": "Palo Alto",
      "state": "California",
      "country": "United States"
    }
  }]
}

PUT
/demo/company/3
{
  "id": 1,
  "name": "Microsoft",
  "emp_count": 3,
  "employees": [{
    "id": 1,
    "name": "Aman",
    "address": {
      "city": "New York",
      "state": "New York",
      "country": "United States"
    }
  }]
}

在地址中搜索India 时,理想情况下,我应该只使用一个嵌套对象获取Facebook,但我会获取所有嵌套对象。如何过滤返回的嵌套对象?

查询示例:

{
  "query": {
    "function_score":{
      "query":{
        "nested":{
         "path":"employees",
         "score_mode":"max",
         "query": {
            "multi_match":{
              "query":"India",
              "type":"cross_fields",
              "fields":[
                "employees.address.city",
                "employees.address.country",
                "employees.address.state"
              ]
            }
          }
        }
      }
    }
  }
}

此查询的输出是 Facebook 与所有员工,而我只想要 Amber

【问题讨论】:

    标签: elasticsearch nested


    【解决方案1】:

    您可以使用inner_hits 获得所需的结果。使用以下查询:

    GET /demo/company/_search
    {
    "query" : {
        "nested" : {
            "path" : "employees",
            "query" : {
                "match" : {"employees.address.country" : "India"}
            },
            "inner_hits" : {} 
        }
      }
    }
    

    输出将是:

    "hits": {
      "total": 1,
      "max_score": 1.4054651,
      "hits": [
         {
            "_index": "demo",
            "_type": "company",
            "_id": "2",
            "_score": 1.4054651,
            "_source": {
               "id": 1,
               "name": "Facebook",
               "emp_count": 3,
               "employees": [
                  {
                     "id": 1,
                     "name": "Amber",
                     "address": {
                        "city": "Bangalore",
                        "state": "Karnataka",
                        "country": "India"
                     }
                  },
                  {
                     "id": 1,
                     "name": "Adrian",
                     "address": {
                        "city": "Palo Alto",
                        "state": "California",
                        "country": "United States"
                     }
                  }
               ]
            },
            "inner_hits": {
               "employees": {
                  "hits": {
                     "total": 1,
                     "max_score": 1.4054651,
                     "hits": [
                        {
                           "_index": "demo",
                           "_type": "company",
                           "_id": "2",
                           "_nested": {
                              "field": "employees",
                              "offset": 0
                           },
                           "_score": 1.4054651,
                           "_source": {
                              "id": 1,
                              "name": "Amber",
                              "address": {
                                 "city": "Bangalore",
                                 "state": "Karnataka",
                                 "country": "India"
                              }
                           }
                        }
                     ]
                  }
               }
            }
         }
        ]
      }
    

    您可以看到,inner_hits 部分只有符合条件的员工。 但是inner_hits 是在 elasticsearch 1.5.0 中引入的。所以版本应该大于elasticsearch 1.5.0。您可以参考here了解更多信息。

    【讨论】:

    • 我可以,但inner_hits 的问题是我不能(或者至少无法弄清楚如何)让排序只拾取匹配的嵌套对象。如果我将emloyees.address.country 更改为United States 并在employees.address.state 上应用排序,Facebookstate 将显示为“Karnataka”,尽管结果不存在于 inner_hits 中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-31
    • 2015-01-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多