请考虑以下集合:
请求->
{
_id : ObjectId("573f28f49b0ffc283676f736"),
date : '2018-12-31',
userId: ObjectId("5c1239e93a7b9a72ef1c9197"),
serviceId: ObjectId("572e29b0116b5db3057bd821"),
status: 'completed'
}
我对请求集合进行了汇总操作,该操作返回以下格式的文档:
{
"grossRequests" : 2,
"grossData" : [
{
"date" : "2018-08-04",
"count" : 1,
"requests" : [
ObjectId("5b658147c73beb5ea3debc6e")
]
},
{
"date" : "2018-08-05",
"count" : 1,
"requests" : [
ObjectId("5b658160572faa5dd033fb48")
]
}
],
"netData" : [
{
"date" : "2018-08-05",
"count" : 1,
"requests" : [
ObjectId("5b658160572faa5dd033fb48")
]
}
],
"netRequests" : 1.0,
"userId" : ObjectId("5c1239e93a7b9a72ef1c9197"),
"serviceId" : "572e29b0116b5db3057bd821"
}
上方是要插入 cumulativeData
中的文档现在,我需要将聚合操作返回的所有文档添加到名为 cumulativeData 的集合中。
cumulativeData 集合具有一个文档,每个服务类型的每个用户ID 。
我正在查询特定的日期范围,并将其插入到集合中时,想“合并”文档,而不是替换它们。
例如,如果我使用forEach遍历聚合操作返回的所有文档,则对于每个新文档,我都会得到{{userId,serviceType}
对,它在 cumulativeData 集合),我需要按原样插入它,对于集合中已经存在的每个文档,我都需要按以下方式进行更新。
grossRequests -> add both values
grossData -> push the new values into the existing set
netData -> push the new values into the existing set
netRequests -> add both values
操作如下,
**累积数据**中的现有文档
{
"grossRequests": 2,
"grossData": [{
"date": "2018-08-04",
"count": 1,
"requests": [
ObjectId("5b658147c73beb5ea3debc6e")
]
}, {
"date": "2018-08-05",
"count": 1,
"requests": [
ObjectId("5b658160572faa5dd033fb48")
]
}
],
"netData": [{
"date": "2018-08-05",
"count": 1,
"requests": [
ObjectId("5b658160572faa5dd033fb48")
]
}
],
"netRequests": 1,
"userId": ObjectId("5c1239e93a7b9a72ef1c9197"),
"serviceId": "572e29b0116b5db3057bd821"
}
在新日期范围内汇总后生成的新文档
{
"grossRequests": 2,
"grossData": [{
"date": "2018-08-04",
"count": 1,
"requests": [
ObjectId("5b658147c73beb5ea3debc8e")
]
}, {
"date": "2018-08-05",
"count": 1,
"requests": [
ObjectId("5b658160572faa5dd033fb4l")
]
}
],
"netData": [{
"date": "2018-08-05",
"count": 1,
"requests": [
ObjectId("5b658160572faa5dd033fb4l")
]
}
],
"netRequests": 1,
"userId": ObjectId("5c1239e93a7b9a72ef1c9197"),
"serviceId": "572e29b0116b5db3057bd821"
}
最终结果
{
"grossRequests": 4,
"grossData": [{
"date": "2018-08-04",
"count": 2,
"requests": [
ObjectId("5b658147c73beb5ea3debc6e") , ObjectId("5b658147c73beb5ea3debc8e")
]
}, {
"date": "2018-08-05",
"count": 2,
"requests": [
ObjectId("5b658160572faa5dd033fb48"), ObjectId("5b658160572faa5dd033fb4l")
]
}
],
"netData": [{
"date": "2018-08-05",
"count": 2,
"requests": [
ObjectId("5b658160572faa5dd033fb48"),ObjectId("5b658160572faa5dd033fb4l")
]
}
],
"netRequests": 2,
"userId": ObjectId("5c1239e93a7b9a72ef1c9197"),
"serviceId": "572e29b0116b5db3057bd821"
}
答案 0 :(得分:1)
您可以使用以下代码执行更新。
当未找到具有用户ID /服务ID的记录时,涉及两个步骤:第一步插入数据,否则更新数据。
在更新步骤中,首先更新顶部字段,即count,然后迭代netData和grossData以执行合并。
要执行合并,我们使用具有n个修改计数的writersult来标识是否必须更新数组值或插入新的数组值。
您可以调整以下查询以满足您的需求。
db.getCollection('requests').aggregate(your aggregation query).forEach(function(doc) {
var user_id = doc.userId;
var service_id = doc.serviceId;
var gross_requests = doc.grossRequests;
var net_requests = doc.netRequests;
var gross_data = doc.grossData;
var net_data = doc.netData;
var matched = db.getCollection('cumulativeData').findOne({
"userId": user_id,
serviceId: service_id
});
if (matched == null) {
db.getCollection('cumulativeData').insert(doc);
} else {
db.getCollection('cumulativeData').update({
"userId": user_id,
serviceId: service_id
}, {
$inc: {
"grossRequests": gross_requests,
"netRequests": net_requests
}
});
gross_data.forEach(function(grdoc) {
var writeresult = db.getCollection('cumulativeData').update({
"userId": user_id,
serviceId: service_id,
"grossData.date": grdoc.date
}, {
$inc: {
"grossData.$.count": grdoc.count
},
$push: {
"grossData.$.requests": {
$each: grdoc.requests
}
}
});
if (writeresult.nModified == 0) {
db.getCollection('cumulativeData').update({
"userId": user_id,
serviceId: service_id
}, {
$push: {
"grossData": {
"count": grdoc.count,
"requests": grdoc.requests,
"date": grdoc.date
}
}
});
}
});
net_data.forEach(function(nrdoc) {
var writeresult = db.getCollection('cumulativeData').update({
"userId": user_id,
serviceId: service_id,
"netData.date": nrdoc.date
}, {
$inc: {
"netData.$.count": nrdoc.count
},
$push: {
"netData.$.requests": {
$each: nrdoc.requests
}
}
});
if (writeresult.nModified == 0) {
db.getCollection('cumulativeData').update({
"userId": user_id,
serviceId: service_id
}, {
$push: {
"netData": {
"count": nrdoc.count,
"requests": nrdoc.requests,
"date": nrdoc.date
}
}
});
}
});
}
});