gpt4 book ai didi

node.js - 查询父级时如何获取 Mongoose 子文档数组中值的聚合总和?

转载 作者:太空宇宙 更新时间:2023-11-03 23:26:36 26 4
gpt4 key购买 nike

我正在尝试在express和mongoose之上构建一些高级的hello world应用程序。假设我有下一个模式:

const pollOptionsSchema = new Schema({
name: String,
votes: {
type: Number,
default: 0
}
});

const pollSchema = new Schema({
name: String,
dateCreated: { type: Date, default: Date.now },
author: { type: Schema.Types.ObjectId },
options: [pollOptionsSchema]
});

当我简单地打电话

Poll.findOne({_id: req.params.id}).exec((err, data) => {
if (err) console.log(err);
// I receive next data:
// { _id: 58ef3d2c526ced15688bd1ea,
// name: 'Question',
// author: 58dcdadfaea29624982e2fc6,
// __v: 0,
// options:
// [ { name: 'stack', _id: 58ef3d2c526ced15688bd1ec, votes: 5 },
// { name: 'overflow', _id: 58ef3d2c526ced15688bd1eb, votes: 3 } ],
// dateCreated: 2017-04-13T08:56:12.044Z }
});

问题是在模型级别调用某些方法后,我如何才能收到相同的数据+合计投票数(即上述情况下的 8 个),例如:

  // I want to receive:
// { _id: 58ef3d2c526ced15688bd1ea,
// name: 'Question',
// author: 58dcdadfaea29624982e2fc6,
// __v: 0,
// totalNumberOfVotes: 8,
// options:
// [ { name: 'stack', _id: 58ef3d2c526ced15688bd1ec, votes: 5 },
// { name: 'overflow', _id: 58ef3d2c526ced15688bd1eb, votes: 3 } ],
// dateCreated: 2017-04-13T08:56:12.044Z }

或者也许我需要在文档级别实现一些额外的方法,即(data.aggregate)?

我已经审核过:

  1. http://mongoosejs.com/docs/api.html#model_Model.mapReduce
  2. http://mongoosejs.com/docs/api.html#aggregate_Aggregate
  3. https://docs.mongodb.com/manual/core/map-reduce/
  4. https://docs.mongodb.com/manual/tutorial/map-reduce-examples/

但不能将其用于我的情况:(

任何建议将不胜感激。谢谢!

最佳答案

使用$reduce $addFields 中的 运算符 管道来创建 totalNumberOfVotes 字段。在聚合管道中,第一步是 $match 它过滤文档流,只允许匹配的文档未经修改地传递到下一个管道阶段,并使用标准 MongoDB 查询。

考虑运行以下聚合操作以获得所需的结果:

Poll.aggregate([
{ "$match": { "_id": mongoose.Types.ObjectId(req.params.id) } },
{
"$addFields": {
"totalNumberOfVotes": {
"$reduce": {
"input": "$options",
"initialValue": 0,
"in": { "$add" : ["$$value", "$$this.votes"] }
}
}
}
}
]).exec((err, data) => {
if (err) console.log(err);
console.log(data);
});

注意:以上内容适用于 MongoDB 3.4 及更高版本。

<小时/>

对于其他早期版本,您需要 $unwind options 数组,然后将非规范化文档分组到 $group 管道步骤并与累加器聚合 $sum , $push $first

以下示例展示了这种方法:

Poll.aggregate([
{ "$match": { "_id": mongoose.Types.ObjectId(req.params.id) } },
{ "$unwind": { "path": "$options", "preserveNullAndEmptyArrays": true } },
{
"$group": {
"_id": "$_id",
"totalNumberOfVotes": { "$sum": "$options.votes" },
"options": { "$push": "$options" },
"name": { "$first": "$name" },
"dateCreated": { "$first": "$dateCreated" },
"author": { "$first": "$author" }
}
}
]).exec((err, data) => {
if (err) console.log(err);
console.log(data);
});

关于node.js - 查询父级时如何获取 Mongoose 子文档数组中值的聚合总和?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43388025/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com