2

I have the following schema:

const userSchema = new Schema({
  local: {
    email: {type: String, unique: true, sparse: true, lowercase: true, trim: true, required: true},
    password: {type: String, required: true},
  },
  username: {type: String, unique: true, lowercase: true, trim: true},
  Items: [{
    name: {type: String, trim: true},
    createdAt: {type: Date, default: Date.now}
  }]
});

And I'm using the following query to retrieve all of the items:

User.findById(req.user.id, 'Items -_id', (err, user) => { ... });

which returns the following:

{ Items: 
   [ 
     { name: 'test1',
       _id: 58c70800a03d09a31bb7fc17,
       createdAt: Mon Mar 13 2017 20:58:40 GMT+0000 (GMT) },
     { name: 'test2',
       _id: 58c70826a03d09a31bb7fc18,
       createdAt: Mon Mar 13 2017 20:59:18 GMT+0000 (GMT) } 
   ] 
}

My question is: How can I edit my mongoose query to return objects inside Items array sorted in descending order based on createdAt property? i.e. so that test2 appears above test1.

(some additional info, the items array on average will be of length 3-10 per user and i'm using Nodejs as the backend, for this reason, would sorting the array on the app side be bearable because of its small size or too inefficient due to Nodejs single threaded nature?), Thanks.

1 Answer 1

1

You can use an aggregation to match your _id, unwind Items array, perform a descending sort and project only Items field :

User.aggregate([{
    "$match": {
        "_id": new mongoose.mongo.ObjectId("58c7fa6987200dfc592d088c")
    }
}, {
    "$unwind": "$Items"
}, {
    "$sort": {
        "Items.createdAt": -1
    }
}, {
    "$group": {
        "Items": {
            "$push": "$Items"
        },
        "_id": 1
    }
}, {
    "$project": {
        "_id": 0,
        "Items": 1
    }
}], function(err, res) {
    console.log(res);
})
Sign up to request clarification or add additional context in comments.

6 Comments

this solution returns the user id for every object inside Items array, how do I exclude the user id from the query result? And also is this query more efficient than doing it client side side with node? Thanks
Add "_id":0 in the project stage to exclude _id. Aggregation is a mongodb feature, it's much more efficient than doing it in nodejs
Thanks a lot, also is it possible to format it the same way as the output in my original question? So it's just an array containing objects, because now it returns an array with objects containing 'Items' key for every object? Thanks
Use a $group, see my updated answer
The returned value is an array containing an object that contains all individual objects within 'Items', but the original output I mentioned in my question, was returning an object pointing to an array containing individual objects within 'Items', how do I edit your answer to change it to that? Thanks
|

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.