Elasticsearch - 聚合多个字段,按计数过滤并按计数排序
Elasticsearch - Aggregating on multiple fields, filtering on count and ordering on count
我对聚合有点陌生,我想创建一个等同于以下 SQL:
select fullname, natcode, count(1) from table where birthdate = '18-sep-1993' group by fullname, natcode having count(1) > 2 order by count(1) desc
所以,如果我有以下数据:
我需要得到如下结果:
如您所见,结果按全名和 natcode 分组,计数>2 并按计数排序
我已设法形成以下查询:
{
"size": 0,
"aggs": {
"profs": {
"filter": {
"term": {
"birthDate": "18-Sep-1993"
}
},
"aggs": {
"name_count": {
"terms": {
"field": "fullName.raw"
},
"aggs": {
"nat_count": {
"terms": {
"field": "natCode"
},
"aggs": {
"my_filter": {
"bucket_selector": {
"buckets_path": {
"the_doc_count": "_count"
},
"script": {
"source": "params.the_doc_count>2"
}
}
}
}
}
}
}
}
}
}
}
实现了什么:
它按日期过滤,在全名 (name_count) 上创建存储桶,在 natcode (nat_count) 上创建子存储桶,并在文档计数上过滤 natcode 存储桶。
这个问题:
我也可以看到空的 name_count 桶。我只想要具有所需数量的桶。以下是结果示例
"aggregations": {
"profs": {
"doc_count": 3754,
"name_count": {
"doc_count_error_upper_bound": 4,
"sum_other_doc_count": 3732,
"buckets": [
{
"key": "JOHN SMITH",
"doc_count": 3,
"nat_count": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "111",
"doc_count": 3
}
]
}
},
{
"key": "MIKE CAIN",
"doc_count": 3,
"nat_count": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "205",
"doc_count": 3
}
]
}
},
{
"key": "JULIA ROBERTS",
"doc_count": 2,
"nat_count": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": []
}
},
{
"key": "JAMES STEPHEN COOK",
"doc_count": 2,
"nat_count": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": []
}
}
在结果中,我不想显示最后两个名字(JULIA ROBERTS 和 JAMES STEPHEN COOK)
另外还缺少什么:
最后对组计数的排序。我希望出现次数最多的组(全名,natcode)
进一步要求:
分组需要在更多的字段上完成,所以它们就像 4 个字段。
如果我使用了任何错误的术语,请原谅。希望您了解需要哪些帮助。谢谢
下面是您的查询应该是怎样的。
必填查询(最终答案)
POST <your_index_name>/_search
{
"size": 0,
"query": {
"bool": {
"filter": {
"term": {
"birthDate": "18-sep-1993"
}
}
}
},
"aggs": {
"groupby_fullname": {
"terms": {
"field": "fullName.raw",
"size": 2000
},
"aggs": {
"natcode_filter": {
"bucket_selector": {
"buckets_path": {
"hits": "groupby_natcode._bucket_count"
},
"script": "params.hits > 0"
}
},
"groupby_natcode": {
"terms": {
"field": "natCode",
"size": 2000,
"min_doc_count": 2
}
}
}
}
}
}
替代解决方案:(类似于 select 不同)
作为最后的手段,我能想到的是做一些类似 select distinct based on fullName + "_" + natCode
的事情。所以基本上你的密钥将是 JOHN SMITH_111
的形式。这确实会给你准确的结果,除了键是这种形式。
POST <your_index_name>/_search
{
"size":0,
"query":{
"bool":{
"filter":{
"term":{
"birthDate":"18-sep-1993"
}
}
}
},
"aggs":{
"name_count":{
"terms":{
"script":{
"inline":"doc['fullName.raw'].value + params.param + doc['natCode'].value",
"lang":"painless",
"params":{
"param":"_"
}
}
},
"aggs":{
"my_filter":{
"bucket_selector":{
"buckets_path":{
"doc_count":"_count"
},
"script":"params.doc_count > 2"
}
}
}
}
}
}
希望对您有所帮助。
我对聚合有点陌生,我想创建一个等同于以下 SQL:
select fullname, natcode, count(1) from table where birthdate = '18-sep-1993' group by fullname, natcode having count(1) > 2 order by count(1) desc
所以,如果我有以下数据:
我需要得到如下结果:
如您所见,结果按全名和 natcode 分组,计数>2 并按计数排序
我已设法形成以下查询:
{
"size": 0,
"aggs": {
"profs": {
"filter": {
"term": {
"birthDate": "18-Sep-1993"
}
},
"aggs": {
"name_count": {
"terms": {
"field": "fullName.raw"
},
"aggs": {
"nat_count": {
"terms": {
"field": "natCode"
},
"aggs": {
"my_filter": {
"bucket_selector": {
"buckets_path": {
"the_doc_count": "_count"
},
"script": {
"source": "params.the_doc_count>2"
}
}
}
}
}
}
}
}
}
}
}
实现了什么: 它按日期过滤,在全名 (name_count) 上创建存储桶,在 natcode (nat_count) 上创建子存储桶,并在文档计数上过滤 natcode 存储桶。
这个问题: 我也可以看到空的 name_count 桶。我只想要具有所需数量的桶。以下是结果示例
"aggregations": {
"profs": {
"doc_count": 3754,
"name_count": {
"doc_count_error_upper_bound": 4,
"sum_other_doc_count": 3732,
"buckets": [
{
"key": "JOHN SMITH",
"doc_count": 3,
"nat_count": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "111",
"doc_count": 3
}
]
}
},
{
"key": "MIKE CAIN",
"doc_count": 3,
"nat_count": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "205",
"doc_count": 3
}
]
}
},
{
"key": "JULIA ROBERTS",
"doc_count": 2,
"nat_count": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": []
}
},
{
"key": "JAMES STEPHEN COOK",
"doc_count": 2,
"nat_count": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": []
}
}
在结果中,我不想显示最后两个名字(JULIA ROBERTS 和 JAMES STEPHEN COOK)
另外还缺少什么: 最后对组计数的排序。我希望出现次数最多的组(全名,natcode)
进一步要求: 分组需要在更多的字段上完成,所以它们就像 4 个字段。
如果我使用了任何错误的术语,请原谅。希望您了解需要哪些帮助。谢谢
下面是您的查询应该是怎样的。
必填查询(最终答案)
POST <your_index_name>/_search
{
"size": 0,
"query": {
"bool": {
"filter": {
"term": {
"birthDate": "18-sep-1993"
}
}
}
},
"aggs": {
"groupby_fullname": {
"terms": {
"field": "fullName.raw",
"size": 2000
},
"aggs": {
"natcode_filter": {
"bucket_selector": {
"buckets_path": {
"hits": "groupby_natcode._bucket_count"
},
"script": "params.hits > 0"
}
},
"groupby_natcode": {
"terms": {
"field": "natCode",
"size": 2000,
"min_doc_count": 2
}
}
}
}
}
}
替代解决方案:(类似于 select 不同)
作为最后的手段,我能想到的是做一些类似 select distinct based on fullName + "_" + natCode
的事情。所以基本上你的密钥将是 JOHN SMITH_111
的形式。这确实会给你准确的结果,除了键是这种形式。
POST <your_index_name>/_search
{
"size":0,
"query":{
"bool":{
"filter":{
"term":{
"birthDate":"18-sep-1993"
}
}
}
},
"aggs":{
"name_count":{
"terms":{
"script":{
"inline":"doc['fullName.raw'].value + params.param + doc['natCode'].value",
"lang":"painless",
"params":{
"param":"_"
}
}
},
"aggs":{
"my_filter":{
"bucket_selector":{
"buckets_path":{
"doc_count":"_count"
},
"script":"params.doc_count > 2"
}
}
}
}
}
}
希望对您有所帮助。