I'm looking for a way to sort a nested array of objects. Here's an example:
answers: [
{name: 'paul', state: 'RU'},
{name: 'steve', state: 'US'},
{name: 'mike', state: 'DE'},
...
]
Suppose now I want to find all the name
, of the answers
array, but sorting it in ascendant order, how can I accomplish that?
I would store it in the order you want it back out. Or sort it after you pull it out, on the client side.
If neither of those are possible, you can use the aggregation framework:
> db.test.insert({answers: [
... {name: 'paul', state: 'RU'},
... {name: 'steve', state: 'US'},
... {name: 'mike', state: 'DE'}]});
> db.test.insert({answers: [
... {name: 'paul', state: 'RU'},
... {name: 'steve', state: 'US'},
... {name: 'xavier', state: 'TX'}]});
db.test.aggregate([
{$unwind: "$answers"},
{$sort: {"answers.name":1}},
{$group: {_id:"$_id", answers: {$push:"$answers"}}}
]);
produces:
{
"result" : [
{
"_id" : ObjectId("5053b2477d820880c3469364"),
"answers" : [
{
"name" : "paul",
"state" : "RU"
},
{
"name" : "steve",
"state" : "US"
},
{
"name" : "xavier",
"state" : "TX"
}
]
},
{
"_id" : ObjectId("5053af9f7d820880c3469363"),
"answers" : [
{
"name" : "mike",
"state" : "DE"
},
{
"name" : "paul",
"state" : "RU"
},
{
"name" : "steve",
"state" : "US"
}
]
}
],
"ok" : 1
}
This might not be helpful in this context, but I thought I'd add this. You also have the option to sort it on the write which tends to be better for denormalized collections where you don't have to sort in more than one way.
I found this situation in my app when creating a feed on a user.
Meteor.users.helpers({
'addToFeed': function (gameId, pushData) {
check(pushData, FeedSchema);
Meteor.users.update({
_id: this._id,
"games.gameId": gameId
}, {
$push: {
"games.$.feed": {
$each: [pushData],
$sort: { timestamp: -1 }
}
}
});
}
});
I found it to be pretty handy because you can then use find()
and it will be sorted by your specifications by default.
After performing a find() you can use sort() on the return value.
db.collection.find({},{"answers.name":1}).sort({"answers.name":1})
The find would extract the name fields of all documents in the collection. The sort would then sort them by name, ascending.
http://www.mongodb.org/display/DOCS/Sorting+and+Natural+Order