我正在尝试在我的mongoDB/Node环境中执行一个相当简单的操作。我所定位的集合中的每个文档都有一个字段"openBalance",这是一个数字值。我想做的是通过将所有这些加在一起来找到totalOpenBalance
。
到目前为止,在查看MongoDB文档时,$add和$sum似乎都用于对集合中的单个文档执行操作,而不是对集合本身执行操作。
这让我想知道,我应该有没有不同的方法来解决这个问题?我尝试了许多结构,但没有一个有效。这是我的完整功能:
exports.getClientData = async function (req, res, next) {
let MongoClient = await require('../config/database')();
let db = MongoClient.connection.db;
let search, skip, pagesize, page, ioOnly = false, client;
let docs = [];
let records = 0;
if (_.isUndefined(req.params)) {
skip = parseInt(req.skip) || 0;
search = JSON.parse(req.search);
pagesize = parseInt(req.pagesize) || 0;
page = parseInt(req.page) || 0;
client = req.client || '';
ioOnly = true;
}
else {
skip = parseInt(req.query.skip) || 0;
search = req.body;
pagesize = parseInt(req.query.pagesize) || 0;
page = parseInt(req.query.page) || 0;
client = req.query.client || '';
}
search = {};
if (skip === 0) {
skip = page * pagesize;
}
if (client) {
let arrClient = [];
arrClient = client.split(",");
if (arrClient) {
// convert each ID to a mongo ID
let mongoArrClient = arrClient.map(client => new mongo.ObjectID(client));
if (mongoArrClient) {
search['client._id'] = { $in: mongoArrClient };
}
}
}
console.log(search);
let counter = 0;
let count = await db.collection('view_client_data').find(search).count();
let totalClients = await db.collection('view_client_data').find(search).count({ $sum: "client._id" });
console.log('totalClients', totalClients);
let totalOpenBalance = await db.collection('view_client_data').find(search).count({ $sum: { "$add" : "openBalance" } });
console.log('totalOpenBalance', totalOpenBalance);
db.collection('view_client_data').find(search).skip(skip).limit(pagesize).forEach(function (doc) {
counter ++; {
console.log(doc);
docs.push(doc);
}
}, function (err) {
if (err) {
if (!ioOnly) {
return next(err);
} else {
return res(err);
}
}
if (ioOnly) {
res({ sessionId: sessID, count: count, data: docs, totalClients: totalClients, totalOpenBalance: totalOpenBalance });
}
else {
res.send({ count: count, data: docs, totalClients: totalClients, totalOpenBalance: totalOpenBalance });
}
});
}
正如您在上面的代码中看到的,我正在使用此代码获取客户端总数:
let totalClients = await db.collection('view_client_data').find(search).count({ $sum: "client._id" });
console.log('totalClients', totalClients);
这非常有效,将客户端的实例相加并给我总数。
同样,为了非常清楚,我遇到一个问题是总结所有openBalance
值的数值。每个文档都有一个字段,openBalance
。我想做的只是将它们相加并输出到标题为 totalOpenBalance
的变量中,并在我发送的响应中传递它,就像我为 totalClients
所做的那样。我尝试了许多选择,包括:
let totalOpenBalance = await db.collection('view_client_data').find(search).count({ $sum: { "$add" : "openBalance" } });
console.log('totalOpenBalance', totalOpenBalance);
而这个:
let totalOpenBalance = await db.collection('view_client_data').find(search).aggregate({ $sum: { "$add" : "openBalance" } });
console.log('totalOpenBalance', totalOpenBalance);
。但正如我所说,没有一个有效。有时我得到一个循环引用错误,有时是一个aggregate is not a function error
,有时不同的错误。我一直在绞尽脑汁试图弄清楚这一点 - 我认为一旦我理解了所需的语法,它就不应该那么复杂。我怎样才能在这里获得我的totalOpenBalance
?
顺便说一下,我的目标文档如下所示:
{
"_id": "3hu40890sf131d361f1ad908",
"client": {
"_id": "4ft9d366121j04563be0b01d6",
"name": {
"first": "John",
"last": "Smith"
}
},
"openBalance": 128,
"lastPurchaseDate": "2018-01-19T00:00:00.000Z"
},
$sum
是一个累加器运算符,必须出现在$group
或$project
聚合管道阶段中。若要同时合并search
筛选器,可以在管道中包含$match
阶段。
let result = await db.collection('view_client_data').aggregate([
{$match: search},
{$group: {_id: null, totalOpenBalance: {$sum: '$openBalance'}}}
]).next();
console.log(result.totalOpenBalance);
我认为$group
就是你要找的。
例如,要计算所有openBalance
字段
db.view_client_data.aggregate(
[
{
$group: {
_id : null
totalOpenBalance: { $sum: "$openBalance" },
}
}
]
)
这应该给你一个像{totalOpenBalance: 900}
这样的对象
这是更多示例的mongodb文档 https://docs.mongodb.com/manual/reference/operator/aggregation/group/#pipe._S_group