Query MongoDB for ordered distinct values

aksamit picture aksamit · Sep 18, 2012 · Viewed 9.5k times · Source

I am using Morphia Java driver for querying a MongoDB that contains a collection of the following form:

MyCollection {
   TypeA
   TypeB
}

I want to retrieve all distinct values of TypeB which I do using the following code:

DBCollection myCol = getDatastore().getCollection(MyCollection.class);
List typeBs = myCol.distinct("TypeB");

Above code works as expected, but list of distinct values is of course not sorted.

I have experimented with the following code:

DBCollection myCol = getDatastore().getCollection(MyCollection.class);
DBObject orderBy = new BasicDBObject("$orderby", new BasicDBObject("TypeB", 1);
List typeBs = myCol.distinct("TypeB", orderBy);

But in this case the list is empty, where are my assumptions wrong?

UPDATE

By using the CLI I found out that the following query returned the expected result:

> db.mycollection.find({$query : {}, $orderby : { TypeB : 1 }})

So I adjusted my code accordingly:

DBCollection myCol = getDatastore().getCollection(MyCollection.class);

BasicDBObject ascending = new BasicDBObject("TypeB", 1);
BasicDBObject filter = new BasicDBObject();
filter.put("$query", new BasicDBObject());
filter.put("$orderby", ascending);

List typeBs = myCol.distinct("TypeB", filter);

Still result contains 0 entries!

What really makes me confused is that the same query works if I use .find instead of .distinct:

DBCollection myCol = getDatastore().getCollection(MyCollection.class);

BasicDBObject ascending = new BasicDBObject("TypeB", 1);
BasicDBObject filter = new BasicDBObject();
filter.put("$query", new BasicDBObject());
filter.put("$orderby", ascending);

myCol.find(filter).hasNext();  <-- Evaluates to TRUE

Why is it that the filter doesn't work when using the distinct method-call?

Answer

blimpyacht picture blimpyacht · Sep 18, 2012

the second DBObject parameter of DBCollection.distinct() is a query object, used to define the matching criteria. To sort the list distincts you can use:

List typeBs = myCol.distinct("TypeB");
java.util.Collections.sort(typeBs);