[英]How to get aggregated sum of values in an array of mongoose subdocuments when query parent?
我正在嘗試在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 }
});
問題是,在Model級別上調用某些方法后,如何才能獲得相同的數據+投票總數(即上述情況下為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)?
我已經查看過:
但不能用於我的情況:(
任何建議將不勝感激。 謝謝!
使用$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);
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.