设置参数 `node.name` 可以自定义 Elasticsearch 节点的名字。 此条 Tips 由 medcl 贡献。

ElasticSearch能否对bucket的结果做筛选?

Elasticsearch | 作者 hjqtlq | 发布于2017年07月27日 | 阅读数:7126

我有一些游戏输赢记录,现在需要统计某个时间段赢的玩家总数和赢的玩家一共赢了多少钱(今天赢100,明天输200算输)

类似这样的语句
select count(user_id), sum(money) as m from log group by user_id where m > 0;
已邀请:

xinfanwang

赞同来自:

筛选出count >2的结果。你可以自己改改条件和参数。

 
         "aggs": {
"make_count": {
"value_count": {
"field": "_index"
}
},
"make_count_bucket_filter": {
"bucket_selector": {
"buckets_path": {
"makeCount": "make_count"
},
"script": "params.makeCount > 2"
}
}

}
....

hjqtlq

赞同来自:

先谢谢你了
但是这个不是我想要的啊
首先,这个没有按照用户ID做聚合(group by user_id)
其次,这个无法运行在顶级节点,如果放在最外面会报错。
Invalid pipeline aggregation named [totalWin_bucket_filter] of type [bucket_selector]. Only sibling pipeline aggregations are allowed at the top level
我就想获得这个时间段赢的玩家总数和这些玩家一共赢了多少钱。
我能通过的唯一比较靠谱的是这样的语句
{
"size": 0,
"aggs": {
"playerList": {
"terms": {
"size": 10000,
"field": "playerId",
"order": {
"totalWin": "asc"
}
},
"aggs": {
"totalWin": {
"sum": {
"field": "addValue"
}
},
"totalWin_bucket_filter": {
"bucket_selector": {
"buckets_path": {
"total_win": "totalWin"
},
"script": "params.total_win > 0"
}
}
}
}
}
}

xinfanwang

赞同来自:

我给的这个是汽车销售的示例数据,按制造商聚合的。聚合结果用"bucket_selector",用script来实现筛选聚合结果。
给你提供个思路而已。

xinfanwang

赞同来自:

类似实现:select count(*) as total from cars  group by make having total > 2

xinfanwang

赞同来自:

完整的DSL:
{
"from": 0,
"size": 0,
"_source": {
"includes": [
"COUNT"
],
"excludes": []
},
"aggregations": {
"make": {
"terms": {
"field": "make",
"size": 200,
"min_doc_count": 1,
"shard_min_doc_count": 0,
"show_term_doc_count_error": false,
"order": [
{
"_count": "desc"
},
{
"_term": "asc"
}
]
},
"aggs": {
"make_count": {
"value_count": {
"field": "_index"
}
},
"make_count_bucket_filter": {
"bucket_selector": {
"buckets_path": {
"makeCount": "make_count"
},
"script": "params.makeCount > 2"
}
}

}
}
}
}

hjqtlq

赞同来自:

按照你的方法改了,但是依然没有得到我想要的我完整的DSL如下:
{
    "index": "logdb_dwc",
    "type": "pumpPlayerMoney",
    "body": {
        "query": {
            "match": {
                "gameId": 1
            }
        },
        "size": 0,
        "aggs": {
            "playerList": {
                "terms": {
                    "size": 2,
                    "min_doc_count": 1,
                    "field": "playerId"
                },
                "aggs": {
                    "totalWin": {
                        "value_count": {
                            "field": "addValue"
                        }
                    },
                    "totalWin_bucket_filter": {
                        "bucket_selector": {
                            "buckets_path": {
                                "total_win": "totalWin"
                            },
                            "script": "params.total_win > 0"
                        }
                    }
                }
            }
        }
    }
}
但是我的得到的结果是:
{
"took": 446,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 58494,
"max_score": 0,
"hits":
},
"aggregations": {
"playerList": {
"doc_count_error_upper_bound": 157,
"sum_other_doc_count": 57937,
"buckets": [
{
"key": 1000054,
"doc_count": 297,
"totalWin": {
"value": 297
}
},
{
"key": 1000164,
"doc_count": 260,
"totalWin": {
"value": 260
}
}
]
}
}
}
依然不是我想要的结果,这里只统计了每一个人的次数,并没有汇总

xinfanwang

赞同来自:

你已经对2级聚合结果过滤成功了。为啥不试试在上一级用同样的方式做sum。每个人都有特定的需求,也有自己的数据源,能帮你的也就提供思路了。原先我试出这个过滤的方法,折腾了一天。

hjqtlq

赞同来自:

bucket_selector这个官方说是非顶级,并且我试验了一下,是不会报错的
Invalid pipeline aggregation named [totalWin_bucket_filter] of type [bucket_selector]. Only sibling pipeline aggregations are allowed at the top level
之前也说个这个问题了。

xsq5112 - 90后编程爱好者

赞同来自:

GET /log /_search
{
  "query": {
    "range": {
      "m": {
        "gt": 0
      }
    }
  }, 
  "aggs": {
    "groupby_userid":{
      "terms": {
        "field": "user_id"
      },"aggs": {
        "sum_money": {
          "sum": {
            "field": "money"
          }
        }
      }
    }
  }
}

mafa1993

赞同来自:

bucket_selector是可以过滤桶的返回结果, 但是在你分桶的时候size 写10的话, 再排序, 然后得到的这十个桶都不满足你bucket_selector的条件, 返回的结果还是空, 我怎么通过bucket_selector 来限制得到桶的个数, 而不是上方的size

要回复问题请先登录注册