给出这样的文档:
var user = {
_id: '53176dc214d1f0d0ec42ae54',
friends: [ '53176dc214d1f0d0ec42ae54', '5317766614d1f0d0ec42ae5e' ]
};
我想在聚合管道中返回每个朋友的数量(作为friend_total)以及前10个朋友ID。
到目前为止我有这个返回我想要的数据 - 我需要相当于朋友的$ slice。
{
$unwind: '$posters',
}, {
$group: {
_id: '$_id',
posters:{$push:'$posters'},
sum: {
$sum: 1
}
}
答案 0 :(得分:4)
不幸的是(在MongoDB 2.6中)聚合管道没有等效的$slice
。在MongoDB问题跟踪器中进行upvote / watch的相关功能请求是SERVER-6074: Allow $slice operator in $project。
有一些不那么美味的解决方法,例如在聚合中返回完整的朋友列表并截断应用程序代码中的数组,或者对find()
和$slice
相关的朋友列表运行多个查询。我的假设是,您的用户平均需要超过10位朋友,因此您希望此查询有效。
我认为你最好的方法是 denormalise 。不要依赖聚合管道来生成前10个朋友ID,而是将这些ID保存到用户文档中的capped array,并在添加/删除新朋友时维护此数组。这确实涉及一些重复的数据,但会快速和简单的查询。同样,您可以使用$inc
为每个用户更新friend_count
朋友,因为他们会添加/删除朋友。
使用此方法,您将不再需要使用aggregate()
来计算朋友数量&前十位朋友,可以使用friend_count
进行排序或作为其他查询或报告的基础。
因此,您的用户文档将显示为:
var user = {
_id: ObjectId("53176dc214d1f0d0ec42ae54"),
friends: [ObjectId("53176dc214d1f0d0ec42ae54"), ObjectId("5317766614d1f0d0ec42ae5e")],
friend_count: 2,
topten: [ObjectId("53176dc214d1f0d0ec42ae54"), ObjectId("5317766614d1f0d0ec42ae5e")],
};