ElasticSearch按多个字段分组

问题描述

由于您只有2个字段,因此一种简单的方法是使用一个方面进行两个查询。对于男性:

{
    "query" : {
      "term" : { "gender" : "Male" }
    },
    "facets" : {
        "age_range" : {
            "terms" : {
                "field" : "age_range"
            }
        }
    }
}

对于女性:

{
    "query" : {
      "term" : { "gender" : "Female" }
    },
    "facets" : {
        "age_range" : {
            "terms" : {
                "field" : "age_range"
            }
        }
    }
}

或者,您也可以使用构面过滤器在单个查询中完成此操作(有关更多信息,请参见此链接

{
    "query" : {
       "match_all": {}
    },
    "facets" : {
        "age_range_male" : {
            "terms" : {
                "field" : "age_range"
            },
            "facet_filter":{
                "term": {
                    "gender": "Male"
                }
            }
        },
        "age_range_female" : {
            "terms" : {
                "field" : "age_range"
            },
            "facet_filter":{
                "term": {
                    "gender": "Female"
                }
            }
        }
    }
}

更新:

由于刻面即将被移除。这是聚合的解决方案:

{
  "query": {
    "match_all": {}
  },
  "aggs": {
    "male": {
      "filter": {
        "term": {
          "gender": "Male"
        }
      },
      "aggs": {
        "age_range": {
          "terms": {
            "field": "age_range"
          }
        }
      }
    },
    "female": {
      "filter": {
        "term": {
          "gender": "Female"
        }
      },
      "aggs": {
        "age_range": {
          "terms": {
            "field": "age_range"
          }
        }
      }
    }
  }
}

解决方法

我发现的唯一接近的事情是:Elasticsearch中的多个分组方式

基本上,我试图获得与以下MySql查询等效的ES :

select gender,age_range,count(distinct profile_id) as count 
FROM TABLE group by age_range,gender

年龄和性别本身很容易获得:

{
  "query": {
    "match_all": {}
  },"facets": {
    "ages": {
      "terms": {
        "field": "age_range","size": 20
      }
    },"gender_by_age": {
      "terms": {
        "fields": [
          "age_range","gender"
        ]
      }
    }
  },"size": 0
}

这使:

{
  "ages": {
    "_type": "terms","missing": 0,"total": 193961,"other": 0,"terms": [
      {
        "term": 0,"count": 162643
      },{
        "term": 3,"count": 10683
      },{
        "term": 4,"count": 8931
      },{
        "term": 5,"count": 4690
      },{
        "term": 6,"count": 3647
      },{
        "term": 2,"count": 3247
      },{
        "term": 1,"count": 120
      }
    ]
  },"total_gender": {
    "_type": "terms","terms": [
      {
        "term": 1,"count": 94799
      },"count": 62645
      },{
        "term": 0,"count": 36517
      }
    ]
  }
}

但是现在我需要这样的东西:

[breakdown_gender] => Array
    (
        [1] => Array
            (
                [0] => 264
                [1] => 1
                [2] => 6
                [3] => 67
                [4] => 72
                [5] => 40
                [6] => 23
            )

        [2] => Array
            (
                [0] => 153
                [2] => 2
                [3] => 21
                [4] => 35
                [5] => 22
                [6] => 11
            )

    )

请注意,这0,1,2,3,4,5,6是针对年龄范围的“映射”,因此它们实际上表示的是:)而不是数字。例如,性别[1](“男性”)细分为[246]的年龄范围[0](“18岁以下”)。