简体   繁体   中英

Sorting with arrays as values in MongoDB using java mongo db driver api

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.

eg

{"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

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)
);

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))));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM