Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

mongoose aggregate $match does not match

Tags:

mongoose

I have an array of objects in which each object contains one array of action objects and one child object. I'd like to sum action points from one specific child id object.

When I test the sum at mongoplaygroundhttps://mongoplayground.net/ it works as expected but in the code, it is not so good. Please, someone, help me to point out what am I missing here?

Bellow It is my files:

array

[
    {
        "_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
    }
]

schema

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);

router

        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;
like image 956
Eliete da Silva Rodrigues Avatar asked Nov 27 '25 11:11

Eliete da Silva Rodrigues


1 Answers

You are trying to aggregate on wrong sample documents, because based on the schema, action field is simply an ObjectId but not an object. It should be simply "child" : ObjectId("5e644fecffc3150013eeafba").

So your aggregation must be like this:

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) will display this in the console:

[ { _id: 5e644fecffc3150013eeafba, totalPointsPerChild: -60 } ]

Playground

like image 73
SuleymanSah Avatar answered Dec 01 '25 06:12

SuleymanSah



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!