Reputation: 33
Sorry for my English.
I want to sort like this, 'initial'
status sort first,then sort by 'create_time'
. Is this possible? I guess the 'aggregate'
may be helpful, but I don't know how it can be used in this condition.
Upvotes: 3
Views: 13581
Reputation: 75934
You can try below aggregation in 3.4 for custom sort.
Use $indexOfArray
to locate the position of "initial", 0 when the status is found else for -1 for all other documents and $addFields
to keep the output index in the extra field in the document followed by $sort
sort on fields.
$project
with exclusion to drop the sort field to get expected output.
When you sort all the initial status document shows at top followed by sort on create_time.
db.col.aggregate([
{
"$addFields":{
"statusValue":{
"$indexOfArray":[
["initial"], "$status"
]
}
}
},
{
"$sort":{
"statusValue":-1, "create_time":-1
}
},
{
"$project":{
"statusValue":0
}
}
])
Upvotes: 5
Reputation: 29
aggregation can be used for advanced custom sort but in this scenario, you can use Sort() method. so let me just give you a small walk through over sort method in Mongo
"sort() method is used To sort documents in MongoDB, you need to use sort() method. The method accepts a document containing a list of fields along with their sorting order. To specify sorting order 1 and -1 are used. 1 is used for ascending order while -1 is used for descending order."
so in your case use sort() method:
Sorting by status than by create_time:
db.test.find().sort({status:-1, create_time:1})
Upvotes: 2
Reputation: 13775
Just to add to Veeram's answer, you can use the standard MongoDB sort()
method (as per Ian Mercer's comment) as well as aggregation. For example:
> db.test.find()
{
"_id": ObjectId("5a6eb96a2937803b14255182"),
"status": "enabled",
"create_time": "2018-01-16"
}
{
"_id": ObjectId("5a6eb9722937803b14255183"),
"status": "enabled",
"create_time": "2018-01-10"
}
{
"_id": ObjectId("5a6eb97b2937803b14255184"),
"status": "disabled",
"create_time": "2018-01-15"
}
{
"_id": ObjectId("5a6eb9892937803b14255185"),
"status": "initial",
"create_time": "2018-01-08"
}
Sorting by status
then by create_time
:
> db.test.find().sort({status:1, create_time:1})
{
"_id": ObjectId("5a6eb97b2937803b14255184"),
"status": "disabled",
"create_time": "2018-01-15"
}
{
"_id": ObjectId("5a6eb9722937803b14255183"),
"status": "enabled",
"create_time": "2018-01-10"
}
{
"_id": ObjectId("5a6eb96a2937803b14255182"),
"status": "enabled",
"create_time": "2018-01-16"
}
{
"_id": ObjectId("5a6eb9892937803b14255185"),
"status": "initial",
"create_time": "2018-01-08"
}
Note that the sorting order on the example above are using string sort, so disabled
will come before enabled
as it is sorting in alphabetical order. Ditto with the create_time
sorting order, which is based on string comparison sort.
For richer options with regards to sorting create_time
, you need to convert the field into an ISODate()
object. See Date() and Data Types in the mongo Shell
One advantage of using cursor sort like this is index use. Properly indexed, the query could be fast without the need to be sorted in memory, since MongoDB uses the index to perform the sort. See Create Indexes to Support Your Queries and Use Indexes to Sort Query Results.
If any of these concepts are new to you, I would suggest you peruse the MongoDB University for free courses about MongoDB.
Upvotes: 2