Ari Jae
Ari Jae

Reputation: 5

Mongo Sort Documents by value in array

I have a list of Students. Each one has an array of points they've earned by category in an array named lightTrail. I want the top 5 people with the most behavior points which is shown at index 1 in the lightTrail array. If it is a tie the second sort field is their total points which is shown at index 0.

Here is what I tried:

db.students.aggregate([{
        $project: {
            fname: 1,
            surname: 1,
            lightTrails: 1,
            '_id': 0
        }
    },
    {
        $sort: {
            "lightTrails.1": -1,
            "lightTrails.0": -1
        }
    }, {
        $limit: 5
    }
], {
    allowDiskUse: true
})

This is the result I wanted:

{
    "fname": "Jim",
    surname: "Jones",
    lightTrails: [200, 70, 30, 30, 15, 15, 40]
}, {
    "fname": "Sean",
    surname: "Marx",
    lightTrails: [180, 50, 50, 20, 20, 15, 25]
}, {
    "fname": "Todd",
    surname: "Lull",
    lightTrails: [150, 40, 60, 15, 15, 10, 10]
}, {
    "fname": "Flynn",
    surname: "Moore",
    lightTrails: [100, 40, 25, 15, 5, 10, 5]
}, {
    "fname": "Al",
    surname: "Ryan",
    lightTrails: [80, 20, 20, 10, 10, 10, 10]
}

The result I got was just 5 students no order:

{
  "fname": "Flynn",
    surname: "Moore",
      lightTrails: [100, 40, 25, 15, 5, 10, 5]
}, {
  "fname": "Jim",
    surname: "Jones",
      lightTrails: [200, 70, 30, 30, 15, 15, 40]
}, {
  "fname": "Al",
    surname: "Ryan",
      lightTrails: [80, 20, 20, 10, 10, 10, 10]
}, {
  "fname": "Todd",
    surname: "Lull",
      lightTrails: [150, 40, 60, 15, 15, 10, 10]
}, {
  "fname": "Sean",
    surname: "Marx",
      lightTrails: [180, 50, 50, 20, 20, 15, 25]
}

I found 2 similar questions but one was for an array of documents which didn't work for me and the other wasn't really asking the same question at all.

Upvotes: 0

Views: 1996

Answers (1)

Datta
Datta

Reputation: 121

You can achieve this by find query. No need to use aggregation.

Query:

db.students.find({},{fname:1,surname:1,lightTrails:1,_id:0}).sort({"lightTrails.0":-1,"lightTrails.1":-1}).limit(5)

Result:

{ "fname" : "Jim", "surname" : "Jones", "lightTrails" : [ 200, 70, 30, 30, 15, 15, 40 ] }
{ "fname" : "Sean", "surname" : "Marx", "lightTrails" : [ 180, 50, 50, 20, 20, 15, 25 ] }
{ "fname" : "Todd", "surname" : "Lull", "lightTrails" : [ 150, 40, 60, 15, 15, 10, 10 ] }
{ "fname" : "Flynn", "surname" : "Moore", "lightTrails" : [ 100, 40, 25, 15, 5, 10, 5 ] }
{ "fname" : "Al", "surname" : "Ryan", "lightTrails" : [ 80, 20, 20, 10, 10, 10, 10 ] }

Upvotes: 6

Related Questions