diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java index bcb101365..b0adb6795 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java @@ -117,15 +117,12 @@ import org.springframework.util.ObjectUtils; import org.springframework.util.ResourceUtils; import org.springframework.util.StringUtils; -import com.mongodb.Cursor; -import com.mongodb.DBCollection; -import com.mongodb.DBCursor; -import com.mongodb.Mongo; import com.mongodb.MongoClient; import com.mongodb.MongoException; import com.mongodb.ReadPreference; import com.mongodb.WriteConcern; import com.mongodb.client.AggregateIterable; +import com.mongodb.client.DistinctIterable; import com.mongodb.client.FindIterable; import com.mongodb.client.MapReduceIterable; import com.mongodb.client.MongoCollection; @@ -164,6 +161,7 @@ import com.mongodb.util.JSONParseException; * @author Laszlo Csontos * @author Maninder Singh * @author Borislav Rangelov + * @author duozhilin */ @SuppressWarnings("deprecation") public class MongoTemplate implements MongoOperations, ApplicationContextAware, IndexOperationsProvider { @@ -799,6 +797,30 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, return doFindOne(collectionName, new Document(idKey, id), new Document(), entityClass); } + public List distinct(String field, Class entityClass, Class resultClass) { + return distinct(new Query(), field, determineCollectionName(entityClass), resultClass); + } + + public List distinct(Query query, String field, Class entityClass, Class resultClass) { + return distinct(query, field, determineCollectionName(entityClass), resultClass); + } + + public List distinct(Query query, String field, String collectionName, Class resultClass) { + MongoCollection collection = this.getCollection(collectionName); + DistinctIterable iterable = collection.distinct(field, query.getQueryObject(), resultClass); + + MongoCursor cursor = iterable.iterator(); + + List result = new ArrayList(); + + while (cursor.hasNext()) { + T object = cursor.next(); + result.add(object); + } + + return result; + } + @Override public GeoResults geoNear(NearQuery near, Class entityClass) { return geoNear(near, entityClass, determineCollectionName(entityClass)); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java index 99781f109..d2f60e04a 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java @@ -113,6 +113,7 @@ import com.mongodb.client.result.UpdateResult; * @author Christoph Strobl * @author Mark Paluch * @author Laszlo Csontos + * @author duozhilin */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:infrastructure.xml") @@ -726,6 +727,39 @@ public class MongoTemplateTests { assertThat(notFound, nullValue()); } + @Test + public void testDistinct() { + Address address1 = new Address(); + address1.state = "PA"; + address1.city = "Philadelphia"; + + Address address2 = new Address(); + address2.state = "PA"; + address2.city = " New York"; + + MyPerson person1 = new MyPerson(); + person1.name = "Ben"; + person1.address = address1; + + MyPerson person2 = new MyPerson(); + person2.name = "Eric"; + person2.address = address2; + + template.save(person1); + template.save(person2); + + List nameList = template.distinct("name", MyPerson.class, String.class); + assertTrue(nameList.containsAll(Arrays.asList(person1.getName(), person2.getName()))); + + Query query = new BasicQuery("{'address.state' : 'PA'}"); + nameList = template.distinct(query, "name", MyPerson.class, String.class); + assertTrue(nameList.containsAll(Arrays.asList(person1.getName(), person2.getName()))); + + String collectionName = template.determineCollectionName(MyPerson.class); + nameList = template.distinct(query, "name", collectionName, String.class); + assertTrue(nameList.containsAll(Arrays.asList(person1.getName(), person2.getName()))); + } + @Test public void testUsingAnInQueryWithObjectId() throws Exception {