如何使用mongodb或robomongo计算价格正负价?

时间:2016-12-10 10:09:40

标签: mongodb mongodb-query aggregation-framework robo3t

下面是我的userpricing集合数据

{
    "_id" : ObjectId("584bc9ba420a6b189c510af6"),
    "user_id" : 1,
    "mobilenumber":"01234",
    "price" : 2000.0,
    "type" : "credit",

},
{
    "_id" : ObjectId("584bc9ba420a6b189c510af6"),
    "user_id" : 1,
    "mobilenumber":"01234",
    "price" : -1000.0,
    "type" : "credit",

},
{
    "_id" : ObjectId("584bc9ba420a6b189c3323w23"),
    "user_id" : 2,
    "mobilenumber":"04321",
    "price" : 1000.0,
    "type" : "credit",

}

这里我想计算所有用户的总负价和总负价,我需要在汇总集合中检查该用户是否存在。如果记录不存在,我们需要在汇总集合中创建文档,如果它存在我们需要更新“Totalpositiveprice”,“Totalnegativeprice”和“Balanceprice”

摘要表中的

已存在此记录

    {

        "user_id": "1",
        "mobilenumber":"01234",
        "Totalpositiveprice": 3000.0,
        "Totalnegativeprice": 0,
        "Balanceprice": 3000.0
    },
   {

        "user_id": "3",
        "mobilenumber":"05555",
        "Totalpositiveprice": 1000.0,
        "Totalnegativeprice": -100,
        "Balanceprice": 900.0
    }
  1. 我们需要更新“mobilenumber”的文档:“01234”,

  2. 我们需要为“mobilenumber”创建新文档:“04321”,

  3. “mobilenumber”:“05555”无需做任何事bcoz在userpricing中没有任何内容

  4. 最后我应该得到像这样的摘要集合

     {
    
            "user_id": "1",
            "mobilenumber":"01234"
            "Totalpositiveprice": 5000.0,
            "Totalnegativeprice": -1000.0,
            "Balanceprice": 4000.0
        },
        {
    
            "user_id": "2",
             "mobilenumber":"04321"
            "Totalpositiveprice": 1000.0,
            "Totalnegativeprice": 0,
            "Balanceprice": 1000.0
        },
        {
    
        "user_id": "3",
        "mobilenumber":"05555",
        "Totalpositiveprice": 1000.0,
        "Totalnegativeprice": -100,
        "Balanceprice": 900.0
    }
    

4 个答案:

答案 0 :(得分:1)

您可以使用conditional sum执行此操作,并使用$out: collectionName

导出另一个集合

可以试试:

db.getCollection('userpricing').aggregate([
    {$group: {
        _id:"$user_id", 
        user_id: {$first: "$user_id"}, 
        Totalpositiveprice:{$sum:{$cond:[{ '$gt': ['$price', 0]}, "$price", 0]}}, 
        Totalnegativeprice:{$sum:{$cond:[{ '$lt': ['$price', 0]}, "$price", 0]}},
        Balanceprice:{"$sum":"$price"}}
     },
     {$project: {_id:0, user_id:1, Totalpositiveprice:1, Totalnegativeprice:1, Balanceprice:1}},
     {$out: "summary"}
])
摘要集合中

N.B:结果导出

答案 1 :(得分:1)

无论你想做什么都涉及复杂的查询。请参阅以下查询。我先解释一下。

1-第一个管道$group对您来说很明显。

需要2秒管道$lookup来生成您想要的结果,因为您希望将当前价格和已汇总的价格编译成一个文档。

3-第三阶段只是展开我们查找的数组summary,以便我们能够编制价格。

4-第四$project阶段正在做你真正想要做的事情,就是说它正在编写你能够理解它的摘要文件。

5-生成摘要集合。

db.getCollection('userpricing').aggregate([
     {$group:{
            _id:"$user_id",
            Totalpositiveprice:{$sum:{$cond:{if:{ $gt:["$price",0]}, then: "$price", else: 0}}},
            Totalnegativeprice:{$sum:{$cond:{if:{ $lt:["$price",0]}, then: "$price", else: 0}}},
            Balanceprice:{"$sum":"$price"}
     }},
     {
      $lookup:
        {
          from: "summary",
          localField: "_id",
          foreignField: "user_id",
          as: "summary"
        }
     },
     {$unwind:{path:"$summary", preserveNullAndEmptyArrays:true}},
     {$project:{
         _id:0,
         user_id:"$_id",
         Balanceprice:{$add:["$Balanceprice", {$cond:{if:{ $eq:["$summary",undefined]}, then: 0, else: "$summary.Balanceprice"}}]},
         Totalnegativeprice:{$add:["$Totalnegativeprice", {$cond:{if:{ $eq:["$summary",undefined]}, then: 0, else: "$summary.Totalnegativeprice"}}]},
         Totalpositiveprice:{$add:["$Totalpositiveprice", {$cond:{if:{ $eq:["$summary",undefined]}, then: 0, else: "$summary.Totalpositiveprice"}}]}
     }},
   {$out:"summary"}  
])

答案 2 :(得分:0)

您可以尝试批量写入批量上传从聚合结果创建的更新查询,并更新summary集合。

这是一个快速代码,您可以尝试使用Mongo shell,您可以根据自己的需要进行调整。

以下代码查询user_id并根据聚合值递增价格值,如果找不到匹配的user_id,则递增价格值。

您应该根据自己的需要更改batch

var bulk = db.getCollection('summary').initializeUnorderedBulkOp();
var count = 0;
var batch = 1;

db.getCollection('userpricing').aggregate([
    {$group: {
        _id:"$user_id", 
        Totalpositiveprice:{$sum:{$cond:[{ '$gt': ['$price', 0]}, "$price", 0]}}, 
        Totalnegativeprice:{$sum:{$cond:[{ '$lt': ['$price', 0]}, "$price", 0]}},
        Balanceprice:{"$sum":"$price"}}
     },
    {$project: {_id:0, user_id:"$_id", Totalpositiveprice:1, Totalnegativeprice:1, Balanceprice:1}}
]).forEach(function(doc){ 
    var user_id = doc.user_id; 
    var totalpositiveprice = doc.Totalpositiveprice; 
    var totalnegativeprice = doc.Totalnegativeprice; 
    var balanceprice = doc.Balanceprice; 
    bulk.find({ "user_id" : user_id }).upsert().updateOne(
      { $inc: {"Totalpositiveprice" : totalpositiveprice, "Totalnegativeprice" : totalnegativeprice, "Balanceprice" : balanceprice } }
   ); 
    count++;  
    if (count == batch) { 
        bulk.execute(); 
        bulk = db.getCollection('summary').initializeUnorderedBulkOp(); 
        count = 0;
    } 
});

if (count > 0) { 
      bulk.execute(); 
 }

答案 3 :(得分:-1)

从其他答案开始,$out的问题在于,如果存在summary集合,它将替换var cursor = db.userpricing.aggregate([ { $group : { _id : "$user_id", Totalpositiveprice : { $sum : { $cond : { if: { $gte : ["$price" , 0]}, then : "$price", else : 0 } } }, Totalnegativeprice : { $sum : { $cond : { if: {$lte : ["$price" , 0]}, then : "$price", else : 0 } } }, Balanceprice : {$sum : "$price"} } }, { $project : { _id : 0, user_id : "$_id", Totalpositiveprice : 1, Totalnegativeprice : 1, Balanceprice : 1 } } ]); while(cursor.hasNext()) { var elem = cursor.next(); db.summary.update( {user_id : elem.user_id}, elem, {upsert : true} ); } > db.summary.find() { "_id" : ObjectId("58564bb71e2cb47f2ddcf1b4"), "Totalpositiveprice" : 10000, "Totalnegativeprice" : 0, "Balanceprice" : 10000, "user_id" : 2 } { "_id" : ObjectId("58564bb71e2cb47f2ddcf1b5"), "Totalpositiveprice" : 20000, "Totalnegativeprice" : -10000, "Balanceprice" : 10000, "user_id" : 1 } 集合,您可能不希望这样。你可以使用一点JavaScript。

public enum PrivilegedAccounts
{
    User = 1,
    Service = 16,
    Admin = 64,
    Other = 1040,
    Executive = 2048
}