在MongoDB中,如何使用聚合框架来获得很少的文档

我正在尝试使用聚合框架,但我有一个问题.

我需要知道我的数据库中有多少人在上个月购买了一些东西.

要做到这一点我使用这个:

db.account.aggregate([
{$project : {civility : 1, 'purchase.date' : 1 }},
{$match: {civility : 1 ,'purchase.date': {$gte: new Date('02/02/2013'), $lt: new Date('02/03/2013')} }},
{$unwind: '$purchase'},
{$match: {civility : 1 ,'purchase.date': {$gte: new Date('02/02/2013'), $lt: new Date('02/03/2013')} }},
{$group: {_id: '$_id', total_buy : {$sum : 1}}},
{$match: {total_buy: {$gte: 2}}},
{$group: {_id: null, total_buyer : {$sum : 1}}}
])

我有这个回应

{
"result" : [
{
"_id" : null,
"total_buyer" : 4443
 }
],
"ok" : 1
}

这个查询工作,因为我使用的日期范围很小,但如果我使用相同的查询,日期范围更大,如下所示:

db.account.aggregate([
{$project : {civility : 1, 'purchase.date' : 1 }},
{$match: {civility : 1 ,'purchase.date': {$gte: new Date('02/01/2013'), $lt: new     Date('03/01/2013')} }},
{$unwind: '$purchase'},
{$match: {civility : 1 ,'purchase.date': {$gte: new Date('02/01/2013'), $lt: new    Date('03/01/2013')} }},
{$group: {_id: '$_id', total_buy : {$sum : 1}}},
{$match: {total_buy: {$gte: 2}}},
{$group: {_id: null, total_buyer : {$sum : 1}}}
])

我有这个 :

{
"errmsg" : "exception: sharded pipeline failed on shard shard0000: { errmsg: \"exception: aggregation result exceeds maximum document size (16MB)\", code: 16389, ok: 0.0 }",
"code" : 16390,
"ok" : 0
}

有什么我做错了或我不能做我需要做的事情?

提前致谢

最佳答案 看起来您可以采取一些措施来改善聚合:

1)添加一个$项目以避免通过你已经使用过的字段(除了_id之外的所有字段)

2)你说你想要购买任何东西的买家数量,但你过滤的只是让买家在这段时间内买了两个或更多“次”或“东西”.

结果:

db.account.aggregate([
   {$project : {civility : 1, 'purchase.date' : 1 }},
   {$match: {civility : 1 ,'purchase.date': {$gte: new Date('02/01/2013'), $lt: new     Date('03/01/2013')} }},
   {$unwind: '$purchase'},
   {$match: {civility : 1 ,'purchase.date': {$gte: new Date('02/01/2013'), $lt: new Date('03/01/2013')} }},
   {$project: {_id  :1}}, 
   {$group: {_id: '$_id', total_buys : {$sum : 1}}},
   {$group: {_id: null, total_buyers : {$sum : 1}}}
])

给定_id字段的大小,只要每个分片匹配不超过420,000个文档,它应该在当前版本(2.4)中有效.每个文件代表购买,我怀疑你可能仍然遇到限制,所以你有几个选择:

1)等到2.6(目前可用作不稳定的开发版本2.5.2),这消除了对数据集大小的限制(这里不是最终大小,但是shard0000必须传回mongos的大小才是问题).
2)使用不同的方法在特定时间段内计算不同的买家(如果这是你真正想要的 – 这不是你的原始聚合所计算的).

点赞