我有一个对象数组,其中每个对象包含一个动作对象数组和一个子对象对象。我想对一个特定的子id对象的动作点求和。
当我在mongoplayground https://mongoplayground.net/测试总和时,它可以按预期工作,但是在代码中却不太理想。 拜托,有人,帮我指出我在这里想念什么?
贝勒,这是我的文件,
数组
[
{
"_id": "5e6990148c3e01001388b678",
"child": {
"image": "",
"_id": "5e695fe97bd186001526798d",
"name": "Mariana",
"gender": "female",
"dateBirth": "12/07/2010",
"createdAt": "2020-03-11T22:02:17.413Z",
"updatedAt": "2020-03-11T22:02:17.413Z",
"__v": 0
},
"actions": [
{
"_id": "5e6990148c3e01001388b679",
"type": "extraNegativePoint",
"point": -10,
"pointType": "red",
"createdAt": "2020-03-12T01:27:48.747Z",
"updatedAt": "2020-03-12T01:27:48.747Z"
},
{
"_id": "5e6990148c3e01001388b67a",
"type": "extraNegativePoint",
"point": -10,
"pointType": "red",
"createdAt": "2020-03-12T01:27:48.747Z",
"updatedAt": "2020-03-12T01:27:48.747Z"
},
{
"_id": "5e6990148c3e01001388b67b",
"type": "extraNegativePoint",
"point": -10,
"pointType": "red",
"createdAt": "2020-03-12T01:27:48.747Z",
"updatedAt": "2020-03-12T01:27:48.747Z"
}
],
"createdAt": "2020-03-12T01:27:48.748Z",
"updatedAt": "2020-03-12T01:27:48.748Z",
"__v": 0
},
{
"_id": "5e6990578c3e01001388b67c",
"child": {
"image": "",
"_id": "5e644fecffc3150013eeafba",
"name": "Sheldon",
"gender": "male",
"dateBirth": "25/01/2014",
"createdAt": "2020-03-08T01:52:44.878Z",
"updatedAt": "2020-03-08T01:52:44.878Z",
"__v": 0
},
"actions": [
{
"_id": "5e6990578c3e01001388b67d",
"type": "extraNegativePoint",
"point": -10,
"pointType": "red",
"createdAt": "2020-03-12T01:28:55.922Z",
"updatedAt": "2020-03-12T01:28:55.922Z"
},
{
"_id": "5e6990578c3e01001388b67e",
"type": "extraNegativePoint",
"point": -10,
"pointType": "red",
"createdAt": "2020-03-12T01:28:55.922Z",
"updatedAt": "2020-03-12T01:28:55.922Z"
},
{
"_id": "5e6990578c3e01001388b67f",
"type": "extraNegativePoint",
"point": -10,
"pointType": "red",
"createdAt": "2020-03-12T01:28:55.923Z",
"updatedAt": "2020-03-12T01:28:55.923Z"
},
{
"_id": "5e6990598c3e01001388b680",
"type": "extraNegativePoint",
"point": -10,
"pointType": "red",
"createdAt": "2020-03-12T01:28:57.428Z",
"updatedAt": "2020-03-12T01:28:57.428Z"
},
{
"_id": "5e6990598c3e01001388b681",
"type": "extraNegativePoint",
"point": -10,
"pointType": "red",
"createdAt": "2020-03-12T01:28:57.428Z",
"updatedAt": "2020-03-12T01:28:57.428Z"
},
{
"_id": "5e6990598c3e01001388b682",
"type": "extraNegativePoint",
"point": -10,
"pointType": "red",
"createdAt": "2020-03-12T01:28:57.428Z",
"updatedAt": "2020-03-12T01:28:57.428Z"
}
],
"createdAt": "2020-03-12T01:28:55.923Z",
"updatedAt": "2020-03-12T01:28:57.431Z",
"__v": 1
}
]
模式
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const Promise = require('promise')
const actionSchema = new Schema({
type: {
type: String,
required: true
},
point: {
type: Number,
min: -1001,
max: 1001,
required: true
},
pointType: {
type: String,
required: true
},
goal:{
type: mongoose.Schema.Types.ObjectId,
ref: 'Goals'
},
penalty: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Penalty'
},
award: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Award'
}
},{
timestamps: true
})
const realizationSchema = new Schema({
child: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Child'
},
actions: [actionSchema]
},
{
timestamps: true
});
realizationSchema.statics.fetchTotalPointsPerChild = function(childId) {
return new Promise((resolve, reject) => {
this.aggregate([
{
$match: {
"child._id": childId
}
},
{
$unwind: "$actions"
},
{
$group: {
_id: "$child._id",
totalPointsPerChild: {
$sum: "$actions.point"
}
}
}],
(err, result) => {
if (err) {
console.log("Error from search: fetchTotalPointsPerChild", err)
return reject(err);
}
resolve(result)
}
)
});
}
module.exports = mongoose.model('Realization', realizationSchema);
路由器
realizationRouter.route('/:childId/actions/totalPoints')
.get((req, res, next) => {
Realization.find()
.populate('child')
.populate('goals')
.populate('penalty')
.then(realization => {
if(realization) {
Realization.fetchTotalPointsPerChild(JSON.stringfy(req.params.childId))
.then(result => {
if(result){
res.statusCode = 200;
res.setHeader('Content-Type', 'application/json');
res.json(result);
}
})
.catch(err => next(err));
} else {
res.statusCode = 200;
res.setHeader('Content-Type', 'application/json');
res.json(`There is no action to show from this child ${req.params.childId}`);
}
})
.catch(err => next(err));
});
module.exports = realizationRouter;
答案 0 :(得分:2)
您正在尝试汇总错误的示例文档,因为基于架构,操作字段只是一个ObjectId,而不是一个对象。应该只是"child" : ObjectId("5e644fecffc3150013eeafba")
。
所以您的汇总必须是这样的:
realizationSchema.statics.fetchTotalPointsPerChild = function(childId) {
return new Promise((resolve, reject) => {
this.aggregate(
[
{
$match: {
child: mongoose.Types.ObjectId(childId) //NOT "child._id": childId
}
},
{
$unwind: "$actions"
},
{
$group: {
_id: "$child", //NOT _id: "$child._id",
totalPointsPerChild: {
$sum: "$actions.point"
}
}
}
],
(err, result) => {
if (err) {
console.log("Error from search: fetchTotalPointsPerChild", err);
return reject(err);
}
console.log(result);
resolve(result);
}
);
});
};
console.log(result)
将在控制台中显示:
[ { _id: 5e644fecffc3150013eeafba, totalPointsPerChild: -60 } ]