如何计算数值并为Mongo/node中的所有文档生成一个值



我正在尝试在我的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

相关内容

最新更新