聚合框架管道中的数组子集

时间:2012-12-20 07:55:29

标签: mongodb aggregation-framework

在之前的question中,我想使用管道操作获取结果组的计数。如上所述,我使用了以下内容:

db.test.aggregate(
    {$unwind: '$tags'}, 
    {$group:{_id: '$tags', count:{$sum:1}}},
    {$project:{tmp:{tag:'$_id', count:'$count'}}}, 
    {$group:{_id:null, total:{$sum:1}, data:{$addToSet:'$tmp'}}}
)

现在知道了计数,我想按页面显示结果,所以我只需要data的子集。我最初的想法是在$slice管道中的data上使用$project,例如:

...
{$project: {data : { $slice: [20,20] }, total: 1}

但似乎$slice不是$project的有效操作。我尝试了一种解决方法:

db.test.aggregate(
    {$unwind: '$tags'}, 
    {$group:{_id: '$tags', count:{$sum:1}}},
    {$project:{tmp:{tag:'$_id', count:'$count'}}}, 
    {$group:{_id:null, total:{$sum:1}, data:{$addToSet:'$tmp'}}},
    {$unwind: '$data'},
    {$skip: 20},
    {$limit: 20}
)

但是看起来,我执行了另一个$unwind管道。有没有更好的解决方案来实现我想做的事情?

2 个答案:

答案 0 :(得分:3)

不幸的是,目前(在MongoDB 2.2中)没有Aggregation Framework运算符到$slice或者取一个数组的子集。

您需要使用以下解决方法:

  • 您在$skip渠道
  • 中使用$limitaggregate()
  • 操纵应用程序代码中的结果。
  • 使用Map/Reduce
  • 实施聚合

MongoDB问题跟踪器中存在一项功能请求,您可以对其进行upvote / watch:SERVER-6074: Allow $slice operator in $project

答案 1 :(得分:0)

正如Stennie所说,mongo的 2.2版本中的聚合框架没有$slice,但在mongo的升级 3.2版本中,他们添加了它

现在您可以使用{{3}}。要从数组的开头或结尾返回元素:{ $slice: [ <array>, <n> ] } 要从数组中的指定位置返回元素:{ $slice: [ <array>, <position>, <n> ] }

来自mongo页面的几个例子:

{ $slice: [ [ 1, 2, 3 ], 1, 1 ] }   // [ 2 ]
{ $slice: [ [ 1, 2, 3 ], -2 ] }     // [ 2, 3 ]
{ $slice: [ [ 1, 2, 3 ], 15, 2 ] }  // [  ]
{ $slice: [ [ 1, 2, 3 ], -15, 2 ] } // [ 1, 2 ]