猫鼬聚合$ match不匹配

时间:2020-03-12 03:29:02

标签: mongoose

我有一个对象数组,其中每个对象包含一个动作对象数组和一个子对象对象。我想对一个特定的子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;

1 个答案:

答案 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 } ]

Playground