Reputation: 3689
Sorting with arrays as values in MongoDB
I have collection with two fields, one with string as a value and second array of strings as a value.
e.g.
{"name" : "User-1", "locations" : ["India", "USA", "UK"]}
{"name" : "User-2", "locations" : ["Russia", "UK", "USA"]}
{"name" : "User-3", "locations" : ["UK", "Japan", "India"]}
{"name" : "User-4", "locations" : ["Japan", "USA", "UK"]}
{"name" : "User-5", "locations" : ["India", "Italy", "Japan"]}
I want to sort on field 'locations'.
Output must be
{"name" : "User-5", "locations" : ["India", "Italy", "Japan"]}
{"name" : "User-1", "locations" : ["India", "USA", "UK"]}
{"name" : "User-4", "locations" : ["Japan", "USA", "UK"]}
{"name" : "User-2", "locations" : ["Russia", "UK", "USA"]}
{"name" : "User-3", "locations" : ["UK", "Japan", "India"]}
How can we do that using mongo db java driver api.
Thanks
Upvotes: 1
Views: 825
Reputation: 50406
You can specify the sort with "dot notation" for each item in the array in order:
db.docs.find().sort({ "locations.0": 1, "locations.1": 1, "locations.2": 1 })
Which would produce:
{ "name" : "User-5", "locations" : [ "India", "Italy", "Japan" ] }
{ "name" : "User-1", "locations" : [ "India", "USA", "UK" ] }
{ "name" : "User-4", "locations" : [ "Japan", "USA", "UK" ] }
{ "name" : "User-2", "locations" : [ "Russia", "UK", "USA" ] }
{ "name" : "User-3", "locations" : [ "UK", "Japan", "India" ] }
So it basically considers the preference in order of each element of the array.
With the basic Java API you just supply the same sort argument:
collection.find().sort(
new Document("locations.0",1)
.append("locations.1",1)
.append("locations.2",1)
);
Upvotes: 1
Reputation: 2868
Try this in mongo console. This uses mongodb aggregation framework:
db.users.aggregate({$sort:{'locations':1}})
Its surprisingly working for me. I have tested using various test samples. Please check the corner cases if any. Following is one of the test case:
> db.users.aggregate({$sort:{'locations':1}})
{ "_id" : ObjectId("5656ce39cb0a925b3d5d16ea"), "name" : "User-6", "locations" : [ "India", "Italy", "Alabama" ] }
{ "_id" : ObjectId("5656ce44cb0a925b3d5d16eb"), "name" : "User-6", "locations" : [ "India", "Italy", "Glabama" ] }
{ "_id" : ObjectId("5656ce75cb0a925b3d5d16ed"), "name" : "User-8", "locations" : [ "India", "Italy", "Glabama", "Cloverfield" ] }
{ "_id" : ObjectId("5656ce63cb0a925b3d5d16ec"), "name" : "User-7", "locations" : [ "India", "Italy", "Glabama", "Govindam" ] }
{ "_id" : ObjectId("5656a65ecb0a925b3d5d16e9"), "name" : "User-5", "locations" : [ "India", "Italy", "Japan" ] }
{ "_id" : ObjectId("5656a65ecb0a925b3d5d16e5"), "name" : "User-1", "locations" : [ "India", "USA", "UK" ] }
{ "_id" : ObjectId("5656a65ecb0a925b3d5d16e8"), "name" : "User-4", "locations" : [ "Japan", "USA", "UK" ] }
{ "_id" : ObjectId("5656a65ecb0a925b3d5d16e6"), "name" : "User-2", "locations" : [ "Russia", "UK", "USA" ] }
{ "_id" : ObjectId("5656a65ecb0a925b3d5d16e7"), "name" : "User-3", "locations" : [ "UK", "Japan", "India" ] }
In Java API it should be something like this:
AggregateIterable<Document> iterable = db.getCollection("users").aggregate(asList(
new Document("$sort", new Document("locations", 1))));
Upvotes: 0