below is my userpricing collection data
{
\"_id\" : ObjectId(\"584bc9ba420a6b189c510af6\"),
\"user_id\" : 1,
\"mobilenumber\":\"01234\",
\"p
You can try bulk write to bulk upload the update queries created from aggregation result and update the summary
collection.
Here is a quick code that you can try from Mongo shell and you can adjust to your needs.
The below code queries for user_id
and increments the price values based on the aggregation values and upserts if no matching user_id is found.
You should change the batch
based on your needs.
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();
}
Whatever you want to do involves a complex query. See the below query. Let me explain it first.
1- first pipeline $group
is obvious to you.
2- second pipeline $lookup
is required to generate your desired result as you want that the current prices and the already summarized prices should be compiled into one document.
3- third stage is just unwinding the array summary
we have looked up so that we will be able to compile the prices.
4- fourth $project
stage is doing what you really want to do that is to say that it is compiling the summary document you will be able to understand it.
5- generating the summary collection.
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"}
])
You can do it by using conditional sum
and export in another collection use $out: collectionName
can try it :
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: result exported in summary collection
As from other answers, the problem with $out
is that it will replace the summary
collection if one exists and you may not want that. You can use a little JavaScript for that.
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 }