在像books : [{ stars: 10, valid: true }, { stars: 24, valid: false }, { stars: 76, valid: true }, ...]
这样的集合中,简单的计算平均值为:
db.books.aggregate([
{ $match : {
valid: true
}},
{ $group : {
_id: null,
avg: { $avg: "$stars" } // <- How calculate $avg of top 20%?
}}
])
但是,如果我想要平均前20%的恒星而不是所有恒星的平均值?
PS:没有知道集合(有效:真)大小,因为与我的例子不同,我执行了很多$unwind
OBS:
> db.version()
2.4.10
答案 0 :(得分:1)
您需要触发两个查询才能实现此目的。
获取valid
属性为true
的明星总数。
var bookCount = db.books.count({"valid":true});
计算需要计算平均值的前20%的记录数。
var limit = Math.ceil(.2*bookCount);
执行聚合操作:
Match
仅限valid
属性为true
的那些记录。Sort
基于stars
属性值的记录,以降序显示
订购,以便顶级明星排在第一位。Limit
前20%的记录。Group
他们并计算他们的平均值。守则:
db.books.aggregate([
{$match:{"valid":true}},
{$sort:{"stars":-1}},
{$limit:limit},
{$group:{"_id":null,"avg":{$avg:"$stars"}}}
])
我执行了很多$ unwind
您的样本数据或您的代码都反映了这一点。