【问题标题】:Inserting/Updating Aggregated data on Mongo在 Mongo 上插入/更新聚合数据
【发布时间】:2019-05-27 17:53:40
【问题描述】:

考虑以下集合:

请求->

{
  _id : ObjectId("573f28f49b0ffc283676f736"),
  date : '2018-12-31',
  userId: ObjectId("5c1239e93a7b9a72ef1c9197"),
  serviceId: ObjectId("572e29b0116b5db3057bd821"),
  status: 'completed'
} 

我对 requests 集合有一个聚合操作,它返回以下格式的文档:

{
    "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 集合有一个文档per userId per serviceType

我正在运行特定日期范围的查询,并且在将它们插入集合时,希望“合并”文档,而不是替换它们。

因此,例如,如果我使用 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"
}

【问题讨论】:

  • 您能否发布一个示例文档用于累积数据收集和预期结果?
  • @Saravana,完成

标签: mongodb mongodb-query aggregation-framework


【解决方案1】:

您可以使用以下代码执行更新。

它涉及两个步骤,第一步是当没有找到用户ID/服务ID的记录时插入数据,否则更新数据。

在更新步骤中,首先更新顶部字段,即计数,然后迭代 netData 和 GrossData 以执行合并。

为了执行合并,我们使用具有 nmodified 计数的 writeresult 来确定我们是否必须更新数组值或插入新数组值。

您可以调整以下查询以满足您的需求。

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
                    }
                }
            });
        }
    });
}

});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-01-20
    • 1970-01-01
    • 2020-10-10
    • 2021-08-23
    • 2015-04-10
    • 2020-03-03
    • 2019-12-12
    • 1970-01-01
    相关资源
    最近更新 更多