Mongoose SUM 被堆叠
Posted
技术标签:
【中文标题】Mongoose SUM 被堆叠【英文标题】:Mongoose SUM get stacked 【发布时间】:2020-02-07 20:25:38 【问题描述】:我正在尝试在 mongoDB 上进行简单的 SUM 以计算单个客户端的价格数量。
我的收藏:
"_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"]
]);
;
会发生什么:
当我现在打开浏览器并调用上面的代码时,我会在终端中看到控制台日志“计算收入”,但在浏览器中它只是永远加载,没有任何反应。
很可能我只是错过了一些愚蠢的小事,但我试图找出它很长一段时间没有任何成功,所以欢迎任何建议。
【问题讨论】:
你没有从控制器返回任何东西(从控制器发送 res),这就是为什么 api 根本没有返回任何东西 这不是关于不返回,而是继续加载:) 所以我的问题不是我没有得到响应,问题是获取永远不会结束 将组更改为 $group:_id:null,total:$sum:"$price" 然后尝试 @sushantmehta 没有任何改变 【参考方案1】:控制器永远不会结束的原因是因为你没有结束响应过程(意思是,你需要使用res
对象并将一些东西发回给调用者)。
为了获取聚合值,还需要执行管道(见this example)。
另外,正如 cmets 中有人指出的那样,您需要在您的组中添加 _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]);
);
在这里,如果你找到123
中的userId
,那么你会得到这个作为回报:
"total": 1000887
但是,如果您将 userId
更改为 1123
,这在您的数据库中不存在,结果将是:
"total": 0
这样,您的客户端始终可以使用相同类型的对象。
另外,我将$project
管道阶段放在那里的原因是为了抑制_id
字段(请参阅here for more info)。
【讨论】:
谢谢@Joseph,你是对的。我能再问一件事吗?现在,如果它不匹配任何内容,它将返回空对象。我可以更改它以使其成为总值为 0 的相同对象吗? @Andurit 很高兴为您提供帮助!当然,请查看答案中的新编辑。我希望这会有所帮助。以上是关于Mongoose SUM 被堆叠的主要内容,如果未能解决你的问题,请参考以下文章
mongoDB,带有 $sum 和 $count 的 mongoose 聚合查询
mongoDB,带有 $sum 和 $count 的 mongoose 聚合查询
Node.js/Mongoose/MongoDb Typescript MapReduce - emit() 和 Array.sum() 方法
Node.js/Mongoose/MongoDb Typescript MapReduce - emit() 和 Array.sum() 方法