Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Distinct in Spring Data MongoDB

Has anyone tried incorporating distinct in their query using Spring Data for Mongo. If you have an example can you please post it. Where and how should I include the distinct flag?

Link to the Spring Data Mongo example -- Example 4.4. Query creation from method names

// Enables the distinct flag for the query
List<Person> findDistinctPeopleByLastnameOrFirstname(String lastname, String firstname);
List<Person> findPeopleDistinctByLastnameOrFirstname(String lastname, String firstname);
like image 426
java_dude Avatar asked Oct 05 '13 23:10

java_dude


4 Answers

After a little poking around, I have come up with the following solution, which is OK and works, but can probably be improved upon. I am still pretty new to Spring, so if you have a better idea, then please do let me know.

Anyway, here it is:

First off, we use the @Autowired annotation to bring in the base MongoTemplate from spring-data-mongodb

@Autowired
MongoTemplate mongoTemplate;

Once we have that, we can use it to make some queries. Note that this is the slightly smelly part because you have to tell Spring what the return type is and it doesn’t really like that…

// Get the distinct stuff from MongoDB
List<String> coll = mongoTemplate.getCollection("mycollection").distinct("myfield");

In the above code you will notice that I have defined a List type variable called coll that uses the @Autowired MongoTemplate variable to get a collection and then a field using distinct. This is analogous to db.whatever.distinct("term") on the Mongo shell.

like image 107
paulscott56 Avatar answered Oct 15 '22 16:10

paulscott56


My environment: spring-data-mongodb 2.0.5,jdk1.8,

Here is my code sample:

import com.mongodb.client.DistinctIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Repository;
import java.util.ArrayList;
import java.util.List;


public List<String> queryAllCategory() {
    List<String> categoryList = new ArrayList<>();
    MongoCollection mongoCollection = mongoTemplate.getCollection("lexicon");
    DistinctIterable distinctIterable = mongoCollection.distinct("category",String.class);
    MongoCursor cursor = distinctIterable.iterator();
    while (cursor.hasNext()) {
        String category = (String)cursor.next();
        categoryList.add(category);
    }
    return categoryList;
}

about distinct method,please read: http://mongodb.github.io/mongo-java-driver/3.7/javadoc/com/mongodb/client/MongoCollection.html#distinct-java.lang.String-java.lang.Class-

like image 35
iengchen Avatar answered Oct 15 '22 16:10

iengchen


Lot has changed since this question was posted. Answering my own question as this question keeps popping up.

Support is there since 3.0 and higher

public DistinctIterable<String> getUniqueTask() {
    return mongoTemplate.getCollection(TABLE).distinct("FIELD", String.class);
}

Side Note: You can even add filters/regex to this query. Read docs. If you cannot find, ping, will post the answer.

like image 8
java_dude Avatar answered Oct 15 '22 16:10

java_dude


Currently MongoDB does not support to retrieve documents in a distinct way. It only supports returning distinct field values using the distinct command.

As it is apparently the latter you're looking for, the bad news is, we currently don't support any projections in derived queries. For progress on this, please follow the related JIRA ticket.

like image 4
Oliver Drotbohm Avatar answered Oct 15 '22 14:10

Oliver Drotbohm