DATAMONGO-1761 - Add distinct operation to MongoTemplate.
We now support distinct queries via MongoTemplate to select distinct field values based on a collection and query.
List<String> distinctNames = template.findDistinct("name", Person.class, String.class);
List<String> distinctNames = template.query(Person.class).distinct("name").as(String.class).all();
Original pull request: #494.
Related pull request: #514.
This commit is contained in:
@@ -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 <T, Z> List<T> distinct(String field, Class<Z> entityClass, Class<T> resultClass) {
|
||||
return distinct(new Query(), field, determineCollectionName(entityClass), resultClass);
|
||||
}
|
||||
|
||||
public <T, Z> List<T> distinct(Query query, String field, Class<Z> entityClass, Class<T> resultClass) {
|
||||
return distinct(query, field, determineCollectionName(entityClass), resultClass);
|
||||
}
|
||||
|
||||
public <T> List<T> distinct(Query query, String field, String collectionName, Class<T> resultClass) {
|
||||
MongoCollection<Document> collection = this.getCollection(collectionName);
|
||||
DistinctIterable<T> iterable = collection.distinct(field, query.getQueryObject(), resultClass);
|
||||
|
||||
MongoCursor<T> cursor = iterable.iterator();
|
||||
|
||||
List<T> result = new ArrayList<T>();
|
||||
|
||||
while (cursor.hasNext()) {
|
||||
T object = cursor.next();
|
||||
result.add(object);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> GeoResults<T> geoNear(NearQuery near, Class<T> entityClass) {
|
||||
return geoNear(near, entityClass, determineCollectionName(entityClass));
|
||||
|
||||
@@ -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<String> 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 {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user