Sagar Chaudhary
Sagar Chaudhary

Reputation: 1403

Sorting on index of array mongodb

I have a collection where i have objects like:

{
    "_id" : ObjectId("5ab212249a639865c58b744e"),
   "levels" : [ 
        {
            "levelId" : 0,
            "siteId" : "5a0ff11dc7bd083ea6a706b1",
            "title" : "Hospital Services"
        }, 
        {
            "levelId" : 1,
            "siteId" : "5a0ff220c7bd083ea6a706d0",
            "title" : "Reference Testing"
        }, 
        {
            "levelId" : 2,
            "siteId" : "5a0ff24fc7bd083ea6a706da",
            "title" : "Des Moines(Reference Testing)"
        }
    ]
}

I want to sort on the title field of 2nd object of levels array e.g. levels.2.title
Currently my mongo query looks like:

db.getCollection('5aaf63a69a639865c58b2ab9').aggregate([
{$sort : {'levels.2.title':1}}
])

But it is not giving desired results.
Please help.

Upvotes: 0

Views: 904

Answers (1)

s7vr
s7vr

Reputation: 75984

You can try below query in 3.6.

db.col.aggregate({$sort:{"levels.2.title":1}});

This aggregation and find semantics are different in 3.4. More on jira here

So

db.col.find().sort({"levels.2.title":1}) 

works as expected and aggregation sort is not working as expected.

Use below aggregation in 3.4.

Use $arrayElemAt to project the second element in $addFields to keep the computed value as the extra field in the document followed by $sort sort on field.

$project with exclusion to drop the sort field to get expected output.

db.col.aggregate([
 {"$addFields":{ "sort_element":{"$arrayElemAt":["$levels", 2]}}}, 
 {"$sort":{"sort_element.title":-1}},
 {"$project":{"sort_element":0}}
])

Also, You can use $let expression to output the title field directly in $addFields stage.

db.col.aggregate([
 {"$addFields":{ "sort_field":{"$let:{"vars":{"ele":{$arrayElemAt":["$levels", 2]}}, in:"$$ele.title"}}}},      
 {"$sort":{"sort_field":-1}},
 {"$project":{"sort_field":0}}
])

Upvotes: 1

Related Questions