Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mongoose - Cannot populate with sort on path notifications.from because it is a subproperty of a document array

I have a very simple mongo scheme I'm accessing with mongoose

I can map the username and firstname to each notification's from field by using populate, the issue is I can't seem to get any sorting to work on the date field

With this code I get an error of

MongooseError: Cannot populate with sort on path notifications.from because it is a subproperty of a document array

Is it possible to do this a different way, or newer way (deep populate, virtuals)? I'm on Mongoose 5.

I'd rather not use vanilla javascript to sort the object afterwards or create a separate schema

var UserSchema = new Schema({  
    username: String,
    firstname: String,
    notifications: [
        {  
            from: { type: Schema.Types.ObjectId, ref: 'User'},
            date: Date,
            desc: String
        }
    ]
});

app.get('/notifications', function(req, res) {
    User.findOne({ _id: req._id }, 'notifications')
    .populate({
        path: 'notifications.from',   
        populate: {
            path: 'from',
            model: 'User',
            options: { sort: { 'notifications.date': -1 } }            
        }
    }) 
    .exec(function(err, user) {
        if (err) console.log(err)
    })
});

That possible duplicate is almost 2 years old about Mongo. I'm asking if there are newer or different ways of doing this in Mongoose as it has changed a bit since 2016 with newer features.

like image 922
totalnoob Avatar asked Mar 15 '18 16:03

totalnoob


1 Answers

From Mongoose V5.0.12 FAQ : http://mongoosejs.com/docs/faq.html#populate_sort_order

Q. I'm populating a nested property under an array like the below code:

new Schema({ arr: [{ child: { ref: 'OtherModel', type: Schema.Types.ObjectId } }] });

.populate({ path: 'arr.child', options: { sort: 'name' } }) won't sort by arr.child.name?

A. See this GitHub issue. It's a known issue but one that's exceptionally difficult to fix.

So unfortunately, for now, it's not possible,

One way to achieve this is to simply use javascript's native sort to sort the notifications after fetching.

.exec(function(err, user) {
    if (err) console.log(err)

    user.notifications.sort(function(a, b){ 
        return new Date(b.date) - new Date(a.date);
    });

})
like image 97
Taki Avatar answered Oct 12 '22 07:10

Taki