Elasticsearch-在嵌套聚合存储桶上应用多级过滤器?

时间:2019-02-18 12:36:32

标签: elasticsearch

我正在尝试通过应用多个过滤器来获取不同的嵌套对象。

基本上,在Elasticsearch中,我将城市作为顶层文档,并将内部的市民文档嵌套在一起,其中又有一个宠物文档嵌套。

我试图让在这三个级别上都具有一定条件的所有公民(城市,公民和宠物):

Give me all distinct citizens 
that have age:"40", 
that have pets "name":"Casper",
from cities with office_type="secondary" 

我知道要过滤第一个级别,我可以使用查询条件,然后,如果需要过滤嵌套的公民,可以在聚合级别添加一个过滤器。

我以本文为例:https://iridakos.com/tutorials/2018/10/22/elasticsearch-bucket-aggregations.html

到目前为止查询工作:

GET city_offices/_search
{
  "size" : 10,
   "query": {
    "term" : { "office_type" : "secondary" } 
  },
  "aggs": {
      "citizens": {
        "nested": {
          "path": "citizens"
        },
        "aggs": {
          "inner_agg": {
            "filter": {
                "term": { "citizens.age": "40" }  
              } ,
              "aggs": {
                  "occupations": {
                    "terms": {
                      "field": "citizens.occupation"
                    }
                  }
              }
          }
        }
      }
    }
}

但是:如何添加“宠物”嵌套过滤条件?

映射:

PUT city_offices
{
  "settings": {
    "number_of_shards": 1
  },
  "mappings": {
    "doc": {
      "properties": {
        "city": {
          "type": "keyword"
        },
        "office_type": {
          "type": "keyword"
        },
        "citizens": {
          "type": "nested",
          "properties": {
            "occupation": {
              "type": "keyword"
            },
            "age": {
              "type": "integer"
            },
            "pets": {
              "type": "nested",
              "properties": {
                "kind": {
                  "type": "keyword"
                  },
                "name": {
                  "type": "keyword"
                },
                "age": {
                  "type": "integer"
                }
              }
            }
          }
        }
      }
    }
  }
}

索引数据:

PUT /city_offices/doc/1
{
   "city":"Athens",
   "office_type":"secondary",
   "citizens":[      
      {
         "occupation":"Statistician",
         "age":30,
         "pets":[
            {
               "kind":"Cat",
               "name":"Phoebe",
               "age":14
            }
         ]
      },
      {
         "occupation":"Librarian",
         "age":30,
         "pets":[
            {
               "kind":"Rabbit",
               "name":"Nino",
               "age":13
            }
         ]
      },   
      {
         "occupation":"Librarian",
         "age":40,
         "pets":[
            {
               "kind":"Rabbit",
               "name":"Nino",
               "age":13
            }
         ]
      },      
      {
         "occupation":"Statistician",
         "age":40,
         "pets":[
            {
               "kind":"Rabbit",
               "name":"Casper",
               "age":2
            },
            {
               "kind":"Rabbit",
               "name":"Nino",
               "age":13
            },
            {
               "kind":"Dog",
               "name":"Nino",
               "age":15
            }
         ]
      }   
   ]
}

1 个答案:

答案 0 :(得分:0)

因此,我找到了解决方案。 基本上,我在查询部分应用顶级过滤器,然后在聚合中应用其余条件。

首先,我应用公民级别的筛选器聚合,然后进入嵌套的宠物并应用筛选器,然后需要恢复到公民级别(使用reverse_nested:公民),然后设置将生成最终存储桶的术语。

查询如下:

              "xxx": {
                "doc_count_error_upper_bound": 0,
                "sum_other_doc_count": 0,
                "buckets": [
                  {
                    "key": "Librarian",
                    "doc_count": 1
                  },
                  {
                    "key": "Statistician",
                    "doc_count": 1
                  }
                ]
              }

响应存储区如下:

//userController.js
router.post('/user/new', function (req, res) {
var newUser = {
    email: req.email,
    first_name: req.first_name,
    last_name: req.last_name,
    phonenumber: req.phonenumber,
    password: req.password
}
console.log(req.email)
User.createUser(newUser, function(err, user){
});

还有其他建议吗?