猫鼬总和堆积

时间:2019-10-10 11:42:05

标签: node.js mongodb express mongoose nosql

我正在尝试在mongoDB上进行微不足道的总和,以计算单个客户端的价格数量。

我的收藏集:

{"_id":"5d973c71dd93adfbda4c7272","name":"Faktura2019006","clientId":"5d9c87a6b9676069c8b5e15b","expiration":"2019-10-02T01:11:18.965Z","price":999999,"userId":"123"},
{"_id":"5d9e07e0b9676069c8b5e15d","name":"Faktura2019007","clientId":"5d9c87a6b9676069c8b5e15b","expiration":"2019-10-02T01:11:18.965Z","price":888,"userId":"123"}

我尝试过的事情:

// invoice.model.js
const mongoose = require("mongoose");

const InvoiceSchema = mongoose.Schema({
  _id: String,
  name: String,
  client: String,
  userId: String,
  expiration: Date,
  price: Number
});

module.exports = mongoose.model("Invoice", InvoiceSchema, "invoice");

// invoice.controller.js
const Invoice = require("../models/invoice.model.js");

exports.income = (req, res) => {
  console.log("Counting Income");

  Invoice.aggregate([
    {
      $match: {
        userId: "123"
      }
    },
    {
      $group: {
        total: { $sum: ["$price"] }
      }
    }
  ]);
};

发生了什么事

当我现在打开浏览器并调用上面的代码时,我在终端中获得控制台日志“ Counting Income”,但是在浏览器中它将永远加载并且什么也没有发生。

很可能我只是想念一些愚蠢的小事,但我试图在很长一段时间内都没有发现任何成功,所以欢迎您提出任何建议。

1 个答案:

答案 0 :(得分:0)

控制器永不结束的原因是因为您没有结束响应过程(这意味着您需要使用res对象并将某些内容发送回调用方)。

为了获得合计值,您还需要执行管道(请参阅this example)。

此外,正如某人在评论中指出的那样,您需要在组中添加_id: null,以指定您不打算按任何特定字段进行分组(请参见second example here)。

最后,在$sum运算符中,对于您要执行的操作,您只需要删除数组括号,因为您只想对单个字段求和(请参见a few examples down here)。

这是修改后的代码:

// invoice.controller.js
const Invoice = require("../models/invoice.model.js");

exports.income = (req, res) => {
  console.log("Counting Income");

  Invoice.aggregate([
    {
      $match: {
        userId: "123"
      }
    },
    {
      $group: {
        _id: null,
        total: { $sum: "$price" }
      }
    }
  ]).then((response) => {
    res.json(response);
  });
};

编辑有关何时返回空数组的注释。

如果您想始终返回相同类型的对象,则可以在控制器中进行控制。我不确定在mongo中是否有一种花哨的方法可以使用聚合管道来做到这一点,但这就是我会做的。

 Invoice.aggregate([
    {
      $match: {
        userId: "123"
      }
    },
    {
      $group: {
        _id: null,
        total: { $sum: "$price" }
      }
    },
    {
      $project: {
        _id: 0,
        total: "$total"
      }
    }
  ]).then((response) => {
    if (response.length === 0) {
      res.json({ total: 0 });
    } else {
      // always return the first (and only) value
      res.json(response[0]);
    }
  });

在这里,如果您发现userId中的123,那么您将得到以下内容:

{
    "total": 1000887
}

但是如果您将userId更改为例如数据库中不存在的1123,则结果将是:

{
    "total": 0
}

这样,您的客户端始终可以使用相同类型的对象。

此外,我将$project流水线放在其中的原因是为了抑制_id字段(请参见here for more info)。

相关问题