6

I'm trying to sort values after executing a find on my MongoDB by Java API. The result list contains the following entries:

{
"_id": "P17-223",
"property": "P17",
"itemid": 223,
"labels": [
  {
    "language": "en",
    "value": "Greenland"
  },
  {
    "language": "es",
    "value": "Groenlandia"
  },
  {
    "language": "de",
    "value": "Grönland"
  }
]

}

I want to sort by the first entry of the array labels:

  DBCursor cursor = getCollection().find(query);
  BasicDBObject orderBy = new BasicDBObject("labels[0].value", 1);
  cursor.sort(orderBy);

Cursor values are not sorted by this code. Can you help me?

5
  • 1
    It might be a lot easier to sort this in the Java code than on the MongoDB layer. Is that OK for you, or do you insist on sorting it on the database? Commented Jul 23, 2014 at 13:58
  • sorting in java is fine, unless you need to query large number of documents Commented Jul 23, 2014 at 14:28
  • 1
    Have you tried BasicDBObject orderBy = new BasicDBObject("labels.0.value", 1); Commented Jul 23, 2014 at 16:26
  • @Mike It's working! Please post this as an answer. I will mark it as accepted. Commented Jul 24, 2014 at 13:40
  • Done, glad it worked for you Commented Jul 24, 2014 at 14:43

4 Answers 4

7

Have you tried

BasicDBObject orderBy = new BasicDBObject("labels.0.value", 1);

It's not obvious, but the MongoDB documentation eludes to it. Using the $ sign matches the first item, but specifying the array element number seems to work. If anyone has a better document describing the behavior, please reply with the link.

From the documentation

Update Documents in an Array

The positional $ operator facilitates updates to arrays that contain embedded
documents. Use the positional $ operator to access the fields in the embedded
documents with the dot notation on the $ operator.

db.collection.update( { <query selector> }, { <update operator>: { "array.$.field" : value } } )


Documentation is here

Sign up to request clarification or add additional context in comments.

Comments

5

I found this question/answer when looking for How to sort MongoDB (in Meteor) by first item of array

I used this to find all documents in the Schedules collection which are active and then sort ascending by the first day in the days array.

Schedules.find(
  {
    active: true,
  },
  {
    sort: { 'days.0': 1 },
  },
)

A sample Schedule collection document with a Monday, Wednesday, Friday schedule looks something like this:

{
  _id: 9dh3ld0d7d0d,
  userId: UJD9dKd8edo,
  active: true,
  days: [1, 3, 5],
}

Comments

1

You cannot actually "sort" by a specific index of an array within a document in MongoDB. ct If you really must do this then you need the aggregation framework to "extract" the element to sort on.

I know the list form is actually deprecated, so this code is just for demonstration. Acutally define your pipeline as individual variables and feed those as argument to aggregate:

    BasicDBList pipeline = new BasicDBList();
    list.add(new BasicDBObject("$unwind","$labels"));
    list.add(new BasicDBObject("$group",
        new BasicDBObject("_id","$_id")
            .append("property", new BasicDBObject("$first","$property"))
            .append("itemid", new BasicDBObject("$first","$itemid"))
            .append("labels", new BasicDBObject("$push","$labels"))
            .append("maxLabel", new BasicDBObject("$max", "$labels.value"))
    ));
    list.add(new BasicDBObject("$sort", new BasicDBObject("maxLabel",1)));

    System.out.println(pipeline);

That gives you the serialized version which is the JSON form of:

db.collection.aggregate([ 
    { "$unwind" : "$labels" }, 
    { "$group": { 
        "_id": "$_id",
        "property": { "$first" : "$property" },
        "itemid": { "$first" : "$itemid" }, 
        "labels": { "$push" : "$labels" },
        "maxLabel": { "$max" : "$labels.value"}
    }}, 
    { "$sort" : { "maxLabel" : 1} }
])

Better applied in your code as:

collection.aggregate(unwind,group,sort);

Where those are individually declared.

1 Comment

Thanks Neil, puh... complicated ;) Thanks Philipp, I will try to sort the elements in the Java code.
0

Since MongoDB 3.0 Java Api, you can use com.mongodb.client.model.Sorts

Exemple use :

col.find().sort(Sorts.orderBy(Sorts.descending(fieldname)));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.