我正在处理一个处理月订单的报告项目 我们有以下格式进入MongoDB的订单
order:{
_id: 123456789012123456789012,
items:[
{code:'ITEM1', qty:5},{code:'ITEM2', qty:6}
]
}
我的要求是找出特定项目如何与所有表现中的其他项目进行排名
我写了这个聚合,首先找出每个项目的分组和订购的数量
db.orders.aggregate(
[
{ $unwind : "$items" },
{ $group : {code : "$code" , tot_ord: { $sum : "$qty" } } },
{ $sort : { tot_ord : -1 } }
]
)
所以这应该给我一个排序最高的订单项目列表。
但是如何在没有循环的情况下获得特定项目的排名?我说的是近500,000个不同的项目,所以我想避免循环
感谢您的帮助。
更新: 这就是我最终的工作。此示例使用Node.js.我发布这个,以便将来对某人有用
function aggregate(mongoDb,collection_item, pipeline, next){
mongoDb.collection(collection_item, function(err, collection) {
collection.aggregate(pipeline,function(err,result) {
if(err){
console.log('Error aggregating: ' + err);
next({'error':'An error has occurred - ' + err});
}else{
next(result);
}
});
});
}
function calculateOrderRank(itemId){
aggregate(mongoDb, "orders",
[
{ $unwind : "$items" },
{ $match : { items.code : itemId} },
{ $group : { _id : "$items.code" , tot_qty: { $sum : "$items.qty" } } }
],function(result) {
var itemQty = result[0].tot_qty;
data.aggregate(mongoDb, "orders",
[
{ $unwind : "$items" },
{ $group : { _id : "$items.code" , tot_qty: { $sum : "$items.qty" } } },
{ $match: {tot_qty:{$gt:itemQty}} },
{ $group : {_id:null, rank : { $sum : 1 } } },
],function(result) {
var rank = 1;
if (result && result.length>0) {
rank = result[0].rank + 1;
}
res.send({item_id:itemId, rank:rank, score:itemQty});
});
}
);
}
答案 0 :(得分:1)
此功能目前在聚合框架中不存在。您需要jira.mongodb.org/browse/SERVER-8065才能获得排名。
同时,您可以使用两个聚合框架查询来执行此操作。
第一个会聚合并获取相关特定项目的总计(它与您在问题中包含的内容类似,但您的$ group格式不正确,应为{$group: {_id:"$items.code", <etc>}
)。您可以从将“items.code”限制为特定值开始。
第二个将用于所有收集,然后在聚合后,您可以{match:{count:{$gt:<count-for-that-one-item>}}
然后再做一个$group
来计算有多少“总数”高于这一个项目。这会给你项目的排名。