4

我正在尝试使用聚合框架,但我有一个问题。我需要知道我的数据库中有多少人在上个月购买了东西。

为此,我使用这个:

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
}

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

提前致谢

4

1 回答 1

2

看起来你可以做几件事来改善你的聚合:

1)添加一个$project以避免通过您已经使用过的字段(除了_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)在特定时间段内使用不同的方法来计算不同的买家(如果那是你真正想要的 - 这不是你最初的聚合计算的)。

于 2013-09-01T20:39:10.813 回答