4

I have a document :

{
    _id: 98556a665626a95a655a,
    first_name: 'Panda',
    last_name: 'Panda,
    notifications: [{
        _id: '',
        // ...
    }]
}

I want to return the following response :

{
   _id: 98556a665626a95a655a,
   first_name: 'Panda',
   last_name: 'Panda',
   notifications: 2
}

The problem is about notifications count field,

I used Mongoose NodeJS package and I tried the following :

UserDBModel.findOne({_id: uid}, {notifications: {$size: '$notifications'}}, function(err, user){ });

But it seems to not work. Someone can help me ? :)

Thanks in advance.

2
  • what did that query return to you? Commented Dec 21, 2015 at 17:01
  • 1
    the $size operator will only return the fields that matches the size specified when used like you used it (It expects a number). If you want it to return the number of items in the array then you must you use it in an aggregration. Here's the link. If not, try using the .length property of an array like suggested in the answers. Commented Dec 21, 2015 at 17:17

3 Answers 3

4

Use aggregate with a project pipeline operator.

UserDBModel.aggregate()
    .match({_id: uid})
    .project({
        first_name: 1,
        last_name: 1,
        notifications: {$size:"$notifications"}
    })
    .exec(function(err, notifications) {
        // notifications will be an array, you probably want notifications[0]
    });

Note that you will have to explicitly specify the fields for the project operator.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks it works ! Just need to add mongoose.Types.ObjectId(uid) instead of uid.
Great man, worked perfectly for me, THANKS
2

Maybe, you could do something like this in your node.

UserDBModel.findOne({ '_id': uid }, 'notifications', function (err, notifications) {
  if (err) return handleError(err);

 console.log(notifications.length);
})

Since you are using JS anyways maybe use its power! :)

2 Comments

Yes but I want to avoid to use memory with notifications array content when I just need to count them.
Okay! If you expect the notification arrays to be huge, then thats the way to go, Mongo will do the heavy lifting for you. But mind you that having boundlessly growing array within a collection in mongodb is a bad design. :)
2

What I found to work for me is creating a mongoose virtual attribute.

Schema.virtual('notifications_count').get(function() {
  if (this.notifications) {
    return this.notifications.length;
  }
});

1 Comment

But how can we get that value in the res ?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.