下面是我的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
}
我们需要更新“mobilenumber”的文档:“01234”,
我们需要为“mobilenumber”创建新文档:“04321”,
“mobilenumber”:“05555”无需做任何事bcoz在userpricing中没有任何内容
最后我应该得到像这样的摘要集合
{
"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
}
答案 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
}