【问题标题】:How can i calculate price positive and negative price using mongodb or robomongo?如何使用 mongodb 或 robomongo 计算价格正负价格?
【发布时间】:2017-04-25 18:05:37
【问题描述】:

以下是我的用户定价收集数据

{
    "_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" 无需做任何事情,因为用户定价中没有任何内容

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

 {

        "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
}

【问题讨论】:

  • 如果余额是指来自 1 个用户的所有价格的总和,那么您在下面有一个答案
  • 差不多,但他/她也想导出到另一个集合中
  • @ShaishabRoy OP 询问的原因是因为他不知道如何进行条件求和而不是如何将结果导出到新集合。
  • 同意你@Styvane

标签: mongodb mongodb-query aggregation-framework robo3t


【解决方案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"}
])

注意:结果导出到摘要集合

【讨论】:

  • 请检查我的问题并帮助我
  • { "user_id": "1", "Totalpositiveprice": "5000.0", "Totalnegativeprice": "-1000", "Balanceprice": "4000.0" }
  • 你能帮我吗@Shaishab Roy
【解决方案2】:

与其他答案一样,$out 的问题在于,如果存在 summary 集合并且您可能不想要它,它将替换它。您可以为此使用一点 JavaScript。

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 }

【讨论】:

  • 它的工作,但对于用户 ID 1,我应该得到这样的 {“user_id”:“1”,“Totalpositiveprice”:“5000.0”,“Totalnegativeprice”:“-1000”,“Balanceprice”: “4000.0”}
  • @itsme: user_iduserpricing 集合中的值是整数/数字。但是在您的摘要集合中,它们是字符串。如果这是您数据库中的实际情况,那么您将不得不进行转换。
【解决方案3】:

您可以尝试批量写入以批量上传从聚合结果创建的更新查询并更新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(); 
 }

【讨论】:

  • 它在 cmd 中不起作用(我使用 mlb,我通过 cmd 连接)
  • 我使用了不正确的集合名称。在答案中修复它。再试一次,看看它是否有效。如果不是,请提供更新代码时出现的错误。注意我是根据用户 ID 而不是手机号码进行分组的。请添加更多详细信息。请确保在两个集合中都使用数值。
  • 它的工作,但用户ID我得到2.0。 { "_id" : ObjectId("58f750889a8a92e6286b91af"), "user_id" : 2.0, "Totalpositiveprice" : 1000.0, "Totalnegativeprice" : 0.0, "Balanceprice" : 1000.0 }
  • 源集合 userpricinguser_id 值为 2.0(float)。这就是您在summary 集合中看到的内容。这不是你所期望的吗?
  • user_id 应该得到 1 和 2 我不想要 2.0 之类的
【解决方案4】:

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

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"}  
])

【讨论】:

  • @its me,如果这解决了你的问题,那么你应该在这里发表评论,这样我才能确保我给出了正确的解决方案。
  • $out 的唯一问题是它会清除整个集合并用您当前的聚合替换它。无法追加到现有集合。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多