0

我正在处理一个处理月度订单的报告项目我们有以下格式的订单进入 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});
                });
            }
    );

}
4

1 回答 1

1

目前聚合框架中不存在此功能。您需要实施jira.mongodb.org/browse/SERVER-8065才能获得排名。

同时,您可以使用两个聚合框架查询来做到这一点。

第一个将汇总并获取相关特定项目的总数(它类似于您在问题中包含的内容,但您的 $group 格式不正确,应该是{$group: {_id:"$items.code", <etc>})。您将从将“items.code”限制为特定值开始。

第二个是所有集合,然后在聚合之后你可以做{match:{count:{$gt:<count-for-that-one-item>}},然后再做另一个$group来计算有多少“总数”高于这个项目。这会给你项目的排名。

于 2013-05-15T06:11:07.810 回答