Search code examples
node.jsmongodbmongooseaggregation-frameworkmongodb-aggregation

Mongoose count certain element in an embedded documents array


I am using mongoose 4.6.3.

I have the following schema :

var mongoose = require('mongoose');
var User = require('./User');

var TicketSchema = new mongoose.Schema({
    user : { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true },
},
{
    timestamps: true
});

var DrawSchema = new mongoose.Schema({
  ...
  max_ticket_per_user : { type : Number, required: true },
  tickets: [TicketSchema]
});

module.exports = mongoose.model('Draw', DrawSchema);

How can I count the embedded documents of a certain User ObjectId(user field in TicketSchema) in a Draw's tickets(tickets field in DrawSchema) ? I want to count the tickets of a user for a single draw.

Would it be better to change my schema design ?

Thanks


Solution

  • You can use the aggregation framework taking advantage of the $filter and $size operators to get the filtered array with elements that match the user id and its size respectively which will subsequently give you the count.

    For an single draw, consider adding a $match pipeline operator as your initial step with the _id query to filter the documents in the collection.

    Consider running the following aggregation pipeline to get the desired result:

    Draw.aggregate([
        { "$match": { "_id": drawId } },
        {
            "$project": {
                "ticketsCount": {
                    "$size": {
                        "$filter": {
                            "input": "$tickets",
                            "as": "item",
                            "cond": { "$eq": [ "$$item.user", userId ] }
                        }
                    }
                }
            }
        }
    ]).exec(function(err, result) {
        console.log(result);
    });