7

My data looks like this:

{
    "name":"dan",
    "somestring":"asdf",
    "friends":[

            {
                "name": "carl",
                "height":180,
                ...
            },
            {
                "name": "john",
                "height":165,
                ...
            },
            {
                "name": "jim",
                "height":170,
                ...
            }

    ]
},
...

I would like retrieve the document where the friends are sorted by height descending.

I tried db.getCollection('users').find({"name" : "dan"}, {"friends" : 1}).sort({"friends.height" : -1}) but the friends list stays the same.

EDIT: I messed up the structure of my data, I fixed the array to look like an array...

McDermott
  • 1,025
  • 2
  • 16
  • 28
  • 1
    Those are "keys" of a sub-document object. You cannot sort them. if you expect to sort by "height" then they need to be in "array" entries themselves. – Neil Lunn Jun 28 '17 at 08:25
  • Good luck with that! Most language implementations do not "by default" have "sorted keys" anyway. JavaScript certainly does not for example. It's really a sign that your chosen structure is incorrect. Named keys are basically an "ant-pattern". It's certainly bad for querying with MongoDB at least. – Neil Lunn Jun 28 '17 at 08:31
  • I messed up the structure, editing... – McDermott Jun 28 '17 at 08:32
  • @McDermott Another solution can be "insert and sort", basically the array inside is sorted at Insert step. So when you will made the Find() you will fetch the results already sorted. If you are interested to this approach i will try to arrange an answer. – Daniele Tassone Jun 28 '17 at 09:30
  • @McDermott i forgot to mention that "insert and sort" is native supported by MongoDB. Let me know if you are interested i will wrote a reply. – Daniele Tassone Jun 28 '17 at 10:40

1 Answers1

13

An option is to run an aggregation that:

  1. unwinds the array
  2. sorts by friends.name
  3. regroups

The pipeline should look something like this:

db.collection.aggregate([
    { $match: { name: 'dan' }},
    { $unwind: '$friends' },
    { $sort: { 'friends.height': -1 }},
    { $group: { _id: '$name', friends: { $push: '$friends'}}])
kewne
  • 2,208
  • 15
  • 11