diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoOperations.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoOperations.java
index 5eef1b52c..cf0c737d1 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoOperations.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoOperations.java
@@ -1,6 +1,6 @@
/*
- * Copyright 2011-2016 the original author or authors.
- *
+ * Copyright 2011-2017 the original author or authors.
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -23,6 +23,7 @@ import org.bson.Document;
import org.springframework.data.geo.GeoResults;
import org.springframework.data.mongodb.core.BulkOperations.BulkMode;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
+import org.springframework.data.mongodb.core.aggregation.AggregationOptions;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.aggregation.TypedAggregation;
import org.springframework.data.mongodb.core.convert.MongoConverter;
@@ -38,7 +39,6 @@ import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.util.CloseableIterator;
import com.mongodb.Cursor;
-import com.mongodb.DB;
import com.mongodb.ReadPreference;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.result.DeleteResult;
@@ -48,7 +48,7 @@ import com.mongodb.client.result.UpdateResult;
* Interface that specifies a basic set of MongoDB operations. Implemented by {@link MongoTemplate}. Not often used but
* a useful option for extensibility and testability (as it can be easily mocked, stubbed, or be the target of a JDK
* proxy).
- *
+ *
* @author Thomas Risberg
* @author Mark Pollack
* @author Oliver Gierke
@@ -56,13 +56,13 @@ import com.mongodb.client.result.UpdateResult;
* @author Chuong Ngo
* @author Christoph Strobl
* @author Thomas Darimont
- * @author maninder
+ * @author Maninder Singh
*/
public interface MongoOperations {
/**
* The collection name used for the specified class by this template.
- *
+ *
* @param entityClass must not be {@literal null}.
* @return
*/
@@ -72,7 +72,7 @@ public interface MongoOperations {
* Execute the a MongoDB command expressed as a JSON string. This will call the method JSON.parse that is part of the
* MongoDB driver to convert the JSON string to a Document. Any errors that result from executing this command will be
* converted into Spring's DAO exception hierarchy.
- *
+ *
* @param jsonCommand a MongoDB command expressed as a JSON string.
*/
Document executeCommand(String jsonCommand);
@@ -80,7 +80,7 @@ public interface MongoOperations {
/**
* Execute a MongoDB command. Any errors that result from executing this command will be converted into Spring's DAO
* exception hierarchy.
- *
+ *
* @param command a MongoDB command
*/
Document executeCommand(Document command);
@@ -88,7 +88,7 @@ public interface MongoOperations {
/**
* Execute a MongoDB command. Any errors that result from executing this command will be converted into Spring's data
* access exception hierarchy.
- *
+ *
* @param command a MongoDB command, must not be {@literal null}.
* @param readPreference read preferences to use, can be {@literal null}.
* @return
@@ -98,7 +98,7 @@ public interface MongoOperations {
/**
* Execute a MongoDB query and iterate over the query results on a per-document basis with a DocumentCallbackHandler.
- *
+ *
* @param query the query class that specifies the criteria used to find a record and also an optional fields
* specification
* @param collectionName name of the collection to retrieve the objects from
@@ -110,7 +110,7 @@ public interface MongoOperations {
* Executes a {@link DbCallback} translating any exceptions as necessary.
*
* Allows for returning a result object, that is a domain object or a collection of domain objects.
- *
+ *
* @param return type
* @param action callback object that specifies the MongoDB actions to perform on the passed in DB instance.
* @return a result object returned by the action or null
@@ -121,7 +121,7 @@ public interface MongoOperations {
* Executes the given {@link CollectionCallback} on the entity collection of the specified class.
*
* Allows for returning a result object, that is a domain object or a collection of domain objects.
- *
+ *
* @param entityClass class that determines the collection to use
* @param return type
* @param action callback object that specifies the MongoDB action
@@ -133,7 +133,7 @@ public interface MongoOperations {
* Executes the given {@link CollectionCallback} on the collection of the given name.
*
* Allows for returning a result object, that is a domain object or a collection of domain objects.
- *
+ *
* @param return type
* @param collectionName the name of the collection that specifies which DBCollection instance will be passed into
* @param action callback object that specifies the MongoDB action the callback action.
@@ -146,7 +146,7 @@ public interface MongoOperations {
* {@link Cursor}.
*
* Returns a {@link CloseableIterator} that wraps the a Mongo DB {@link Cursor} that needs to be closed.
- *
+ *
* @param element return type
* @param query must not be {@literal null}.
* @param entityType must not be {@literal null}.
@@ -160,7 +160,7 @@ public interface MongoOperations {
* by a Mongo DB {@link Cursor}.
*
* Returns a {@link CloseableIterator} that wraps the a Mongo DB {@link Cursor} that needs to be closed.
- *
+ *
* @param element return type
* @param query must not be {@literal null}.
* @param entityType must not be {@literal null}.
@@ -172,7 +172,7 @@ public interface MongoOperations {
/**
* Create an uncapped collection with a name based on the provided entity class.
- *
+ *
* @param entityClass class that determines the collection to create
* @return the created collection
*/
@@ -180,7 +180,7 @@ public interface MongoOperations {
/**
* Create a collection with a name based on the provided entity class using the options.
- *
+ *
* @param entityClass class that determines the collection to create
* @param collectionOptions options to use when creating the collection.
* @return the created collection
@@ -189,7 +189,7 @@ public interface MongoOperations {
/**
* Create an uncapped collection with the provided name.
- *
+ *
* @param collectionName name of the collection
* @return the created collection
*/
@@ -197,7 +197,7 @@ public interface MongoOperations {
/**
* Create a collection with the provided name and options.
- *
+ *
* @param collectionName name of the collection
* @param collectionOptions options to use when creating the collection.
* @return the created collection
@@ -206,7 +206,7 @@ public interface MongoOperations {
/**
* A set of collection names.
- *
+ *
* @return list of collection names
*/
Set getCollectionNames();
@@ -215,7 +215,7 @@ public interface MongoOperations {
* Get a collection by name, creating it if it doesn't exist.
*
* Translate any exceptions as necessary.
- *
+ *
* @param collectionName name of the collection
* @return an existing collection or a newly created one.
*/
@@ -225,7 +225,7 @@ public interface MongoOperations {
* Check to see if a collection with a name indicated by the entity class exists.
*
* Translate any exceptions as necessary.
- *
+ *
* @param entityClass class that determines the name of the collection
* @return true if a collection with the given name is found, false otherwise.
*/
@@ -235,7 +235,7 @@ public interface MongoOperations {
* Check to see if a collection with a given name exists.
*
* Translate any exceptions as necessary.
- *
+ *
* @param collectionName name of the collection
* @return true if a collection with the given name is found, false otherwise.
*/
@@ -245,7 +245,7 @@ public interface MongoOperations {
* Drop the collection with the name indicated by the entity class.
*
* Translate any exceptions as necessary.
- *
+ *
* @param entityClass class that determines the collection to drop/delete.
*/
void dropCollection(Class entityClass);
@@ -254,21 +254,21 @@ public interface MongoOperations {
* Drop the collection with the given name.
*
* Translate any exceptions as necessary.
- *
+ *
* @param collectionName name of the collection to drop/delete.
*/
void dropCollection(String collectionName);
/**
* Returns the operations that can be performed on indexes
- *
+ *
* @return index operations on the named collection
*/
IndexOperations indexOps(String collectionName);
/**
* Returns the operations that can be performed on indexes
- *
+ *
* @return index operations on the named collection associated with the given entity class
*/
IndexOperations indexOps(Class> entityClass);
@@ -283,7 +283,7 @@ public interface MongoOperations {
/**
* Returns a new {@link BulkOperations} for the given collection.
- *
+ *
* @param mode the {@link BulkMode} to use for bulk operations, must not be {@literal null}.
* @param collectionName the name of the collection to work on, must not be {@literal null} or empty.
* @return {@link BulkOperations} on the named collection
@@ -292,7 +292,7 @@ public interface MongoOperations {
/**
* Returns a new {@link BulkOperations} for the given entity type.
- *
+ *
* @param mode the {@link BulkMode} to use for bulk operations, must not be {@literal null}.
* @param entityType the name of the entity class, must not be {@literal null}.
* @return {@link BulkOperations} on the named collection associated of the given entity class.
@@ -301,7 +301,7 @@ public interface MongoOperations {
/**
* Returns a new {@link BulkOperations} for the given entity type and collection name.
- *
+ *
* @param mode the {@link BulkMode} to use for bulk operations, must not be {@literal null}.
* @param entityClass the name of the entity class, must not be {@literal null}.
* @param collectionName the name of the collection to work on, must not be {@literal null} or empty.
@@ -317,7 +317,7 @@ public interface MongoOperations {
*
* If your collection does not contain a homogeneous collection of types, this operation will not be an efficient way
* to map objects since the test for class type is done in the client and not on the server.
- *
+ *
* @param entityClass the parameterized type of the returned list
* @return the converted collection
*/
@@ -331,7 +331,7 @@ public interface MongoOperations {
*
* If your collection does not contain a homogeneous collection of types, this operation will not be an efficient way
* to map objects since the test for class type is done in the client and not on the server.
- *
+ *
* @param entityClass the parameterized type of the returned list.
* @param collectionName name of the collection to retrieve the objects from
* @return the converted collection
@@ -341,7 +341,7 @@ public interface MongoOperations {
/**
* Execute a group operation over the entire collection. The group operation entity class should match the 'shape' of
* the returned object that takes int account the initial document structure as well as any finalize functions.
- *
+ *
* @param criteria The criteria that restricts the row that are considered for grouping. If not specified all rows are
* considered.
* @param inputCollectionName the collection where the group operation will read from
@@ -356,7 +356,7 @@ public interface MongoOperations {
* Execute a group operation restricting the rows to those which match the provided Criteria. The group operation
* entity class should match the 'shape' of the returned object that takes int account the initial document structure
* as well as any finalize functions.
- *
+ *
* @param criteria The criteria that restricts the row that are considered for grouping. If not specified all rows are
* considered.
* @param inputCollectionName the collection where the group operation will read from
@@ -370,7 +370,7 @@ public interface MongoOperations {
/**
* Execute an aggregation operation. The raw results will be mapped to the given entity class. The name of the
* inputCollection is derived from the inputType of the aggregation.
- *
+ *
* @param aggregation The {@link TypedAggregation} specification holding the aggregation operations, must not be
* {@literal null}.
* @param collectionName The name of the input collection to use for the aggreation.
@@ -380,13 +380,10 @@ public interface MongoOperations {
*/
AggregationResults aggregate(TypedAggregation> aggregation, String collectionName, Class outputType);
- CloseableIterator aggregateStream(TypedAggregation> aggregation, String inputCollectionName,
- Class outputType);
-
/**
* Execute an aggregation operation. The raw results will be mapped to the given entity class. The name of the
* inputCollection is derived from the inputType of the aggregation.
- *
+ *
* @param aggregation The {@link TypedAggregation} specification holding the aggregation operations, must not be
* {@literal null}.
* @param outputType The parameterized type of the returned list, must not be {@literal null}.
@@ -396,52 +393,109 @@ public interface MongoOperations {
AggregationResults aggregate(TypedAggregation> aggregation, Class outputType);
/**
- * Execute an aggregation operation. The raw results will be mapped to the given entity class and are returned as
- * stream. The name of the inputCollection is derived from the inputType of the aggregation.
+ * Execute an aggregation operation. The raw results will be mapped to the given entity class.
*
- * @param aggregation The {@link TypedAggregation} specification holding the aggregation operations, must not be
+ * @param aggregation The {@link Aggregation} specification holding the aggregation operations, must not be
* {@literal null}.
+ * @param inputType the inputType where the aggregation operation will read from, must not be {@literal null} or
+ * empty.
* @param outputType The parameterized type of the returned list, must not be {@literal null}.
* @return The results of the aggregation operation.
- * @since 1.11.0
+ * @since 1.3
*/
- CloseableIterator aggregateStream(TypedAggregation> aggregation, Class outputType);
-
+ AggregationResults aggregate(Aggregation aggregation, Class> inputType, Class outputType);
/**
* Execute an aggregation operation. The raw results will be mapped to the given entity class.
- *
+ *
* @param aggregation The {@link Aggregation} specification holding the aggregation operations, must not be
* {@literal null}.
- * @param inputType the inputType where the aggregation operation will read from, must not be {@literal null} or
+ * @param collectionName the collection where the aggregation operation will read from, must not be {@literal null} or
* empty.
* @param outputType The parameterized type of the returned list, must not be {@literal null}.
* @return The results of the aggregation operation.
* @since 1.3
*/
- AggregationResults aggregate(Aggregation aggregation, Class> inputType, Class outputType);
+ AggregationResults aggregate(Aggregation aggregation, String collectionName, Class outputType);
+
+ /**
+ * Execute an aggregation operation backed by a Mongo DB {@link Cursor}.
+ *
+ * Returns a {@link CloseableIterator} that wraps the a Mongo DB {@link Cursor} that needs to be closed. The raw
+ * results will be mapped to the given entity class. The name of the inputCollection is derived from the inputType of
+ * the aggregation.
+ *
+ * Aggregation streaming can't be used with {@link AggregationOptions#isExplain() aggregation explain}. Enabling
+ * explanation mode will throw an {@link IllegalArgumentException}.
+ *
+ * @param aggregation The {@link TypedAggregation} specification holding the aggregation operations, must not be
+ * {@literal null}.
+ * @param collectionName The name of the input collection to use for the aggreation.
+ * @param outputType The parameterized type of the returned list, must not be {@literal null}.
+ * @return The results of the aggregation operation.
+ * @since 2.0
+ */
+ CloseableIterator aggregateStream(TypedAggregation> aggregation, String collectionName, Class outputType);
+
+ /**
+ * Execute an aggregation operation backed by a Mongo DB {@link Cursor}.
+ *
+ * Returns a {@link CloseableIterator} that wraps the a Mongo DB {@link Cursor} that needs to be closed. The raw
+ * results will be mapped to the given entity class and are returned as stream. The name of the inputCollection is
+ * derived from the inputType of the aggregation.
+ *
+ * Aggregation streaming can't be used with {@link AggregationOptions#isExplain() aggregation explain}. Enabling
+ * explanation mode will throw an {@link IllegalArgumentException}.
+ *
+ * @param aggregation The {@link TypedAggregation} specification holding the aggregation operations, must not be
+ * {@literal null}.
+ * @param outputType The parameterized type of the returned list, must not be {@literal null}.
+ * @return The results of the aggregation operation.
+ * @since 2.0
+ */
+ CloseableIterator aggregateStream(TypedAggregation> aggregation, Class outputType);
+ /**
+ * Execute an aggregation operation backed by a Mongo DB {@link Cursor}.
+ *
+ * Returns a {@link CloseableIterator} that wraps the a Mongo DB {@link Cursor} that needs to be closed. The raw
+ * results will be mapped to the given entity class.
+ *
+ * Aggregation streaming can't be used with {@link AggregationOptions#isExplain() aggregation explain}. Enabling
+ * explanation mode will throw an {@link IllegalArgumentException}.
+ *
+ * @param aggregation The {@link Aggregation} specification holding the aggregation operations, must not be
+ * {@literal null}.
+ * @param inputType the inputType where the aggregation operation will read from, must not be {@literal null} or
+ * empty.
+ * @param outputType The parameterized type of the returned list, must not be {@literal null}.
+ * @return The results of the aggregation operation.
+ * @since 2.0
+ */
CloseableIterator aggregateStream(Aggregation aggregation, Class> inputType, Class outputType);
/**
- * Execute an aggregation operation. The raw results will be mapped to the given entity class.
- *
+ * Execute an aggregation operation backed by a Mongo DB {@link Cursor}.
+ *
+ * Returns a {@link CloseableIterator} that wraps the a Mongo DB {@link Cursor} that needs to be closed. The raw
+ * results will be mapped to the given entity class.
+ *
+ * Aggregation streaming can't be used with {@link AggregationOptions#isExplain() aggregation explain}. Enabling
+ * explanation mode will throw an {@link IllegalArgumentException}.
+ *
* @param aggregation The {@link Aggregation} specification holding the aggregation operations, must not be
* {@literal null}.
* @param collectionName the collection where the aggregation operation will read from, must not be {@literal null} or
* empty.
* @param outputType The parameterized type of the returned list, must not be {@literal null}.
* @return The results of the aggregation operation.
- * @since 1.3
+ * @since 2.0
*/
- AggregationResults aggregate(Aggregation aggregation, String collectionName, Class outputType);
-
CloseableIterator aggregateStream(Aggregation aggregation, String collectionName, Class outputType);
-
/**
* Execute a map-reduce operation. The map-reduce operation will be formed with an output type of INLINE
- *
+ *
* @param inputCollectionName the collection where the map-reduce will read from
* @param mapFunction The JavaScript map function
* @param reduceFunction The JavaScript reduce function
@@ -454,7 +508,7 @@ public interface MongoOperations {
/**
* Execute a map-reduce operation that takes additional map-reduce options.
- *
+ *
* @param inputCollectionName the collection where the map-reduce will read from
* @param mapFunction The JavaScript map function
* @param reduceFunction The JavaScript reduce function
@@ -468,7 +522,7 @@ public interface MongoOperations {
/**
* Execute a map-reduce operation that takes a query. The map-reduce operation will be formed with an output type of
* INLINE
- *
+ *
* @param query The query to use to select the data for the map phase
* @param inputCollectionName the collection where the map-reduce will read from
* @param mapFunction The JavaScript map function
@@ -482,7 +536,7 @@ public interface MongoOperations {
/**
* Execute a map-reduce operation that takes a query and additional map-reduce options
- *
+ *
* @param query The query to use to select the data for the map phase
* @param inputCollectionName the collection where the map-reduce will read from
* @param mapFunction The JavaScript map function
@@ -499,7 +553,7 @@ public interface MongoOperations {
* information to determine the collection the query is ran against. Note, that MongoDB limits the number of results
* by default. Make sure to add an explicit limit to the {@link NearQuery} if you expect a particular number of
* results.
- *
+ *
* @param near must not be {@literal null}.
* @param entityClass must not be {@literal null}.
* @return
@@ -510,7 +564,7 @@ public interface MongoOperations {
* Returns {@link GeoResults} for all entities matching the given {@link NearQuery}. Note, that MongoDB limits the
* number of results by default. Make sure to add an explicit limit to the {@link NearQuery} if you expect a
* particular number of results.
- *
+ *
* @param near must not be {@literal null}.
* @param entityClass must not be {@literal null}.
* @param collectionName the collection to trigger the query against. If no collection name is given the entity class
@@ -528,7 +582,7 @@ public interface MongoOperations {
*
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
* feature rich {@link Query}.
- *
+ *
* @param query the query class that specifies the criteria used to find a record and also an optional fields
* specification
* @param entityClass the parameterized type of the returned list.
@@ -545,7 +599,7 @@ public interface MongoOperations {
*
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
* feature rich {@link Query}.
- *
+ *
* @param query the query class that specifies the criteria used to find a record and also an optional fields
* specification
* @param entityClass the parameterized type of the returned list.
@@ -556,7 +610,7 @@ public interface MongoOperations {
/**
* Determine result of given {@link Query} contains at least one element.
- *
+ *
* @param query the {@link Query} class that specifies the criteria used to find a record.
* @param collectionName name of the collection to check for objects.
* @return
@@ -565,7 +619,7 @@ public interface MongoOperations {
/**
* Determine result of given {@link Query} contains at least one element.
- *
+ *
* @param query the {@link Query} class that specifies the criteria used to find a record.
* @param entityClass the parameterized type.
* @return
@@ -574,7 +628,7 @@ public interface MongoOperations {
/**
* Determine result of given {@link Query} contains at least one element.
- *
+ *
* @param query the {@link Query} class that specifies the criteria used to find a record.
* @param entityClass the parameterized type.
* @param collectionName name of the collection to check for objects.
@@ -590,7 +644,7 @@ public interface MongoOperations {
*
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
* feature rich {@link Query}.
- *
+ *
* @param query the query class that specifies the criteria used to find a record and also an optional fields
* specification
* @param entityClass the parameterized type of the returned list.
@@ -606,7 +660,7 @@ public interface MongoOperations {
*
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
* feature rich {@link Query}.
- *
+ *
* @param query the query class that specifies the criteria used to find a record and also an optional fields
* specification
* @param entityClass the parameterized type of the returned list.
@@ -618,7 +672,7 @@ public interface MongoOperations {
/**
* Returns a document with the given id mapped onto the given class. The collection the query is ran against will be
* derived from the given target class as well.
- *
+ *
* @param
* @param id the id of the document to return.
* @param entityClass the type the document shall be converted into.
@@ -628,7 +682,7 @@ public interface MongoOperations {
/**
* Returns the document with the given id from the given collection mapped onto the given target class.
- *
+ *
* @param id the id of the document to return
* @param entityClass the type to convert the document to
* @param collectionName the collection to query for the document
@@ -638,9 +692,9 @@ public interface MongoOperations {
T findById(Object id, Class entityClass, String collectionName);
/**
- * Triggers findAndModify
- * to apply provided {@link Update} on documents matching {@link Criteria} of given {@link Query}.
- *
+ * Triggers findAndModify
+ * to apply provided {@link Update} on documents matching {@link Criteria} of given {@link Query}.
+ *
* @param query the {@link Query} class that specifies the {@link Criteria} used to find a record and also an optional
* fields specification.
* @param update the {@link Update} to apply on matching documents.
@@ -650,9 +704,9 @@ public interface MongoOperations {
T findAndModify(Query query, Update update, Class entityClass);
/**
- * Triggers findAndModify
- * to apply provided {@link Update} on documents matching {@link Criteria} of given {@link Query}.
- *
+ * Triggers findAndModify
+ * to apply provided {@link Update} on documents matching {@link Criteria} of given {@link Query}.
+ *
* @param query the {@link Query} class that specifies the {@link Criteria} used to find a record and also an optional
* fields specification.
* @param update the {@link Update} to apply on matching documents.
@@ -663,10 +717,10 @@ public interface MongoOperations {
T findAndModify(Query query, Update update, Class entityClass, String collectionName);
/**
- * Triggers findAndModify
- * to apply provided {@link Update} on documents matching {@link Criteria} of given {@link Query} taking
+ * Triggers findAndModify
+ * to apply provided {@link Update} on documents matching {@link Criteria} of given {@link Query} taking
* {@link FindAndModifyOptions} into account.
- *
+ *
* @param query the {@link Query} class that specifies the {@link Criteria} used to find a record and also an optional
* fields specification.
* @param update the {@link Update} to apply on matching documents.
@@ -677,10 +731,10 @@ public interface MongoOperations {
T findAndModify(Query query, Update update, FindAndModifyOptions options, Class entityClass);
/**
- * Triggers findAndModify
- * to apply provided {@link Update} on documents matching {@link Criteria} of given {@link Query} taking
+ * Triggers findAndModify
+ * to apply provided {@link Update} on documents matching {@link Criteria} of given {@link Query} taking
* {@link FindAndModifyOptions} into account.
- *
+ *
* @param query the {@link Query} class that specifies the {@link Criteria} used to find a record and also an optional
* fields specification.
* @param update the {@link Update} to apply on matching documents.
@@ -690,7 +744,7 @@ public interface MongoOperations {
* @return
*/
T findAndModify(Query query, Update update, FindAndModifyOptions options, Class entityClass,
- String collectionName);
+ String collectionName);
/**
* Map the results of an ad-hoc query on the collection for the entity type to a single instance of an object of the
@@ -701,7 +755,7 @@ public interface MongoOperations {
*
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
* feature rich {@link Query}.
- *
+ *
* @param query the query class that specifies the criteria used to find a record and also an optional fields
* specification
* @param entityClass the parameterized type of the returned list.
@@ -718,7 +772,7 @@ public interface MongoOperations {
*
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
* feature rich {@link Query}.
- *
+ *
* @param query the query class that specifies the criteria used to find a record and also an optional fields
* specification
* @param entityClass the parameterized type of the returned list.
@@ -729,7 +783,7 @@ public interface MongoOperations {
/**
* Returns the number of documents for the given {@link Query} by querying the collection of the given entity class.
- *
+ *
* @param query
* @param entityClass must not be {@literal null}.
* @return
@@ -740,7 +794,7 @@ public interface MongoOperations {
* Returns the number of documents for the given {@link Query} querying the given collection. The given {@link Query}
* must solely consist of document field references as we lack type information to map potential property references
* onto document fields. TO make sure the query gets mapped, use {@link #count(Query, Class, String)}.
- *
+ *
* @param query
* @param collectionName must not be {@literal null} or empty.
* @return
@@ -751,7 +805,7 @@ public interface MongoOperations {
/**
* Returns the number of documents for the given {@link Query} by querying the given collection using the given entity
* class to map the given {@link Query}.
- *
+ *
* @param query
* @param entityClass must not be {@literal null}.
* @param collectionName must not be {@literal null} or empty.
@@ -772,7 +826,7 @@ public interface MongoOperations {
*
*
* Insert is used to initially store the object into the database. To update an existing object use the save method.
- *
+ *
* @param objectToSave the object to store in the collection.
*/
void insert(Object objectToSave);
@@ -784,7 +838,7 @@ public interface MongoOperations {
* configured otherwise, an instance of MappingMongoConverter will be used.
*
* Insert is used to initially store the object into the database. To update an existing object use the save method.
- *
+ *
* @param objectToSave the object to store in the collection
* @param collectionName name of the collection to store the object in
*/
@@ -792,7 +846,7 @@ public interface MongoOperations {
/**
* Insert a Collection of objects into a collection in a single batch write to the database.
- *
+ *
* @param batchToSave the list of objects to save.
* @param entityClass class that determines the collection to use
*/
@@ -800,7 +854,7 @@ public interface MongoOperations {
/**
* Insert a list of objects into the specified collection in a single batch write to the database.
- *
+ *
* @param batchToSave the list of objects to save.
* @param collectionName name of the collection to store the object in
*/
@@ -809,7 +863,7 @@ public interface MongoOperations {
/**
* Insert a mixed Collection of objects into a database collection determining the collection name to use based on the
* class.
- *
+ *
* @param collectionToSave the list of objects to save.
*/
void insertAll(Collection extends Object> objectsToSave);
@@ -826,7 +880,7 @@ public interface MongoOperations {
* property type will be handled by Spring's BeanWrapper class that leverages Type Conversion API. See
*
* Spring's Type Conversion" for more details.
- *
+ *
* @param objectToSave the object to store in the collection
*/
void save(Object objectToSave);
@@ -843,7 +897,7 @@ public interface MongoOperations {
* property type will be handled by Spring's BeanWrapper class that leverages Type Cobnversion API. See Spring's
* Type Conversion" for more details.
- *
+ *
* @param objectToSave the object to store in the collection
* @param collectionName name of the collection to store the object in
*/
@@ -852,7 +906,7 @@ public interface MongoOperations {
/**
* Performs an upsert. If no document is found that matches the query, a new document is created and inserted by
* combining the query document and the update document.
- *
+ *
* @param query the query document that specifies the criteria used to select a record to be upserted
* @param update the update document that contains the updated object or $ operators to manipulate the existing object
* @param entityClass class that determines the collection to use
@@ -863,7 +917,7 @@ public interface MongoOperations {
/**
* Performs an upsert. If no document is found that matches the query, a new document is created and inserted by
* combining the query document and the update document.
- *
+ *
* @param query the query document that specifies the criteria used to select a record to be updated
* @param update the update document that contains the updated object or $ operators to manipulate the existing
* object.
@@ -875,7 +929,7 @@ public interface MongoOperations {
/**
* Performs an upsert. If no document is found that matches the query, a new document is created and inserted by
* combining the query document and the update document.
- *
+ *
* @param query the query document that specifies the criteria used to select a record to be upserted
* @param update the update document that contains the updated object or $ operators to manipulate the existing object
* @param entityClass class of the pojo to be operated on
@@ -887,7 +941,7 @@ public interface MongoOperations {
/**
* Updates the first object that is found in the collection of the entity class that matches the query document with
* the provided update document.
- *
+ *
* @param query the query document that specifies the criteria used to select a record to be updated
* @param update the update document that contains the updated object or $ operators to manipulate the existing
* object.
@@ -899,7 +953,7 @@ public interface MongoOperations {
/**
* Updates the first object that is found in the specified collection that matches the query document criteria with
* the provided updated document.
- *
+ *
* @param query the query document that specifies the criteria used to select a record to be updated
* @param update the update document that contains the updated object or $ operators to manipulate the existing
* object.
@@ -911,7 +965,7 @@ public interface MongoOperations {
/**
* Updates the first object that is found in the specified collection that matches the query document criteria with
* the provided updated document.
- *
+ *
* @param query the query document that specifies the criteria used to select a record to be updated
* @param update the update document that contains the updated object or $ operators to manipulate the existing
* object.
@@ -924,7 +978,7 @@ public interface MongoOperations {
/**
* Updates all objects that are found in the collection for the entity class that matches the query document criteria
* with the provided updated document.
- *
+ *
* @param query the query document that specifies the criteria used to select a record to be updated
* @param update the update document that contains the updated object or $ operators to manipulate the existing
* object.
@@ -936,7 +990,7 @@ public interface MongoOperations {
/**
* Updates all objects that are found in the specified collection that matches the query document criteria with the
* provided updated document.
- *
+ *
* @param query the query document that specifies the criteria used to select a record to be updated
* @param update the update document that contains the updated object or $ operators to manipulate the existing
* object.
@@ -948,7 +1002,7 @@ public interface MongoOperations {
/**
* Updates all objects that are found in the collection for the entity class that matches the query document criteria
* with the provided updated document.
- *
+ *
* @param query the query document that specifies the criteria used to select a record to be updated
* @param update the update document that contains the updated object or $ operators to manipulate the existing
* object.
@@ -960,14 +1014,14 @@ public interface MongoOperations {
/**
* Remove the given object from the collection by id.
- *
+ *
* @param object
*/
DeleteResult remove(Object object);
/**
* Removes the given object from the given collection.
- *
+ *
* @param object
* @param collection must not be {@literal null} or empty.
*/
@@ -976,7 +1030,7 @@ public interface MongoOperations {
/**
* Remove all documents that match the provided query document criteria from the the collection used to store the
* entityClass. The Class parameter is also used to help convert the Id of the object if it is present in the query.
- *
+ *
* @param query
* @param entityClass
*/
@@ -985,7 +1039,7 @@ public interface MongoOperations {
/**
* Remove all documents that match the provided query document criteria from the the collection used to store the
* entityClass. The Class parameter is also used to help convert the Id of the object if it is present in the query.
- *
+ *
* @param query
* @param entityClass
* @param collectionName
@@ -995,7 +1049,7 @@ public interface MongoOperations {
/**
* Remove all documents from the specified collection that match the provided query document criteria. There is no
* conversion/mapping done for any criteria using the id field.
- *
+ *
* @param query the query document that specifies the criteria used to remove a record
* @param collectionName name of the collection where the objects will removed
*/
@@ -1003,7 +1057,7 @@ public interface MongoOperations {
/**
* Returns and removes all documents form the specified collection that match the provided query.
- *
+ *
* @param query
* @param collectionName
* @return
@@ -1013,7 +1067,7 @@ public interface MongoOperations {
/**
* Returns and removes all documents matching the given query form the collection used to store the entityClass.
- *
+ *
* @param query
* @param entityClass
* @return
@@ -1025,7 +1079,7 @@ public interface MongoOperations {
* Returns and removes all documents that match the provided query document criteria from the the collection used to
* store the entityClass. The Class parameter is also used to help convert the Id of the object if it is present in
* the query.
- *
+ *
* @param query
* @param entityClass
* @param collectionName
@@ -1036,7 +1090,7 @@ public interface MongoOperations {
/**
* Returns the underlying {@link MongoConverter}.
- *
+ *
* @return
*/
MongoConverter getConverter();
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 3bbc60a41..f3e11c048 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
@@ -15,26 +15,14 @@
*/
package org.springframework.data.mongodb.core;
-import static org.springframework.data.mongodb.core.aggregation.AggregationOptions.*;
import static org.springframework.data.mongodb.core.query.Criteria.*;
import static org.springframework.data.mongodb.core.query.SerializationUtils.*;
import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
import java.util.Map.Entry;
-import java.util.Scanner;
-import java.util.Set;
import java.util.concurrent.TimeUnit;
-import com.mongodb.*;
import org.bson.Document;
import org.bson.conversions.Bson;
import org.bson.types.ObjectId;
@@ -69,6 +57,7 @@ import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.BulkOperations.BulkMode;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationOperationContext;
+import org.springframework.data.mongodb.core.aggregation.AggregationOptions;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.aggregation.Fields;
import org.springframework.data.mongodb.core.aggregation.TypeBasedAggregationOperationContext;
@@ -112,6 +101,16 @@ import org.springframework.util.ObjectUtils;
import org.springframework.util.ResourceUtils;
import org.springframework.util.StringUtils;
+import com.mongodb.CommandResult;
+import com.mongodb.Cursor;
+import com.mongodb.DBCollection;
+import com.mongodb.DBCursor;
+import com.mongodb.Mongo;
+import com.mongodb.MongoException;
+import com.mongodb.ReadPreference;
+import com.mongodb.WriteConcern;
+import com.mongodb.WriteResult;
+import com.mongodb.client.AggregateIterable;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MapReduceIterable;
import com.mongodb.client.MongoCollection;
@@ -126,7 +125,6 @@ import com.mongodb.client.model.UpdateOptions;
import com.mongodb.client.result.DeleteResult;
import com.mongodb.client.result.UpdateResult;
import com.mongodb.util.JSONParseException;
-import com.mongodb.AggregationOptions;
/**
* Primary implementation of {@link MongoOperations}.
@@ -146,7 +144,7 @@ import com.mongodb.AggregationOptions;
* @author Niko Schmuck
* @author Mark Paluch
* @author Laszlo Csontos
- * @author maninder
+ * @author Maninder Singh
*/
@SuppressWarnings("deprecation")
public class MongoTemplate implements MongoOperations, ApplicationContextAware, IndexOperationsProvider {
@@ -365,8 +363,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
FindIterable cursor = collection.find(mappedQuery).projection(mappedFields);
QueryCursorPreparer cursorPreparer = new QueryCursorPreparer(query, entityType);
- ReadDocumentCallback readCallback = new ReadDocumentCallback(mongoConverter, entityType,
- collectionName);
+ ReadDocumentCallback readCallback = new ReadDocumentCallback(mongoConverter, entityType, collectionName);
return new CloseableIterableCursorAdapter(cursorPreparer.prepare(cursor), exceptionTranslator, readCallback);
}
@@ -1527,16 +1524,17 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
return new GroupByResults(mappedResults, commandResult);
}
+ /* (non-Javadoc)
+ * @see org.springframework.data.mongodb.core.MongoOperations#aggregate(org.springframework.data.mongodb.core.aggregation.TypedAggregation, java.lang.Class)
+ */
@Override
public AggregationResults aggregate(TypedAggregation> aggregation, Class outputType) {
return aggregate(aggregation, determineCollectionName(aggregation.getInputType()), outputType);
}
- @Override
- public CloseableIterator aggregateStream(TypedAggregation> aggregation, Class outputType) {
- return aggregateStream(aggregation, determineCollectionName(aggregation.getInputType()), outputType);
- }
-
+ /* (non-Javadoc)
+ * @see org.springframework.data.mongodb.core.MongoOperations#aggregate(org.springframework.data.mongodb.core.aggregation.TypedAggregation, java.lang.String, java.lang.Class)
+ */
@Override
public AggregationResults aggregate(TypedAggregation> aggregation, String inputCollectionName,
Class outputType) {
@@ -1548,6 +1546,27 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
return aggregate(aggregation, inputCollectionName, outputType, context);
}
+ /* (non-Javadoc)
+ * @see org.springframework.data.mongodb.core.MongoOperations#aggregate(org.springframework.data.mongodb.core.aggregation.Aggregation, java.lang.Class, java.lang.Class)
+ */
+ @Override
+ public AggregationResults aggregate(Aggregation aggregation, Class> inputType, Class outputType) {
+
+ return aggregate(aggregation, determineCollectionName(inputType), outputType,
+ new TypeBasedAggregationOperationContext(inputType, mappingContext, queryMapper));
+ }
+
+ /* (non-Javadoc)
+ * @see org.springframework.data.mongodb.core.MongoOperations#aggregate(org.springframework.data.mongodb.core.aggregation.Aggregation, java.lang.String, java.lang.Class)
+ */
+ @Override
+ public AggregationResults aggregate(Aggregation aggregation, String collectionName, Class outputType) {
+ return aggregate(aggregation, collectionName, outputType, null);
+ }
+
+ /* (non-Javadoc)
+ * @see org.springframework.data.mongodb.core.MongoOperations#aggregateStream(org.springframework.data.mongodb.core.aggregation.TypedAggregation, java.lang.String, java.lang.Class)
+ */
@Override
public CloseableIterator aggregateStream(TypedAggregation> aggregation, String inputCollectionName,
Class outputType) {
@@ -1559,13 +1578,17 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
return aggregateStream(aggregation, inputCollectionName, outputType, context);
}
+ /* (non-Javadoc)
+ * @see org.springframework.data.mongodb.core.MongoOperations#aggregateStream(org.springframework.data.mongodb.core.aggregation.TypedAggregation, java.lang.Class)
+ */
@Override
- public AggregationResults aggregate(Aggregation aggregation, Class> inputType, Class outputType) {
-
- return aggregate(aggregation, determineCollectionName(inputType), outputType,
- new TypeBasedAggregationOperationContext(inputType, mappingContext, queryMapper));
+ public CloseableIterator aggregateStream(TypedAggregation> aggregation, Class outputType) {
+ return aggregateStream(aggregation, determineCollectionName(aggregation.getInputType()), outputType);
}
+ /* (non-Javadoc)
+ * @see org.springframework.data.mongodb.core.MongoOperations#aggregateStream(org.springframework.data.mongodb.core.aggregation.Aggregation, java.lang.Class, java.lang.Class)
+ */
@Override
public CloseableIterator aggregateStream(Aggregation aggregation, Class> inputType, Class outputType) {
@@ -1573,11 +1596,9 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
new TypeBasedAggregationOperationContext(inputType, mappingContext, queryMapper));
}
- @Override
- public AggregationResults aggregate(Aggregation aggregation, String collectionName, Class outputType) {
- return aggregate(aggregation, collectionName, outputType, null);
- }
-
+ /* (non-Javadoc)
+ * @see org.springframework.data.mongodb.core.MongoOperations#aggregateStream(org.springframework.data.mongodb.core.aggregation.Aggregation, java.lang.String, java.lang.Class)
+ */
@Override
public CloseableIterator aggregateStream(Aggregation aggregation, String collectionName, Class outputType) {
return aggregateStream(aggregation, collectionName, outputType, null);
@@ -1677,8 +1698,8 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
return mappedResults;
}
- protected CloseableIterator aggregateStream(final Aggregation aggregation, final String collectionName,
- final Class outputType, AggregationOperationContext context) {
+ protected CloseableIterator aggregateStream(Aggregation aggregation, String collectionName,
+ Class outputType, AggregationOperationContext context) {
Assert.hasText(collectionName, "Collection name must not be null or empty!");
Assert.notNull(aggregation, "Aggregation pipeline must not be null!");
@@ -1686,35 +1707,53 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
AggregationOperationContext rootContext = context == null ? Aggregation.DEFAULT_CONTEXT : context;
- final DBObject command = aggregation.toDbObject(collectionName, rootContext);
+ Document command = aggregation.toDocument(collectionName, rootContext);
+
+ assertNotExplain(command);
+
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug("Streaming aggregation: {}", serializeToJsonSafely(command));
+ }
- Assert.isNull(command.get(CURSOR), "Custom options not allowed while streaming");
- Assert.isNull(command.get(EXPLAIN), "Explain option can't be used while streaming");
+ ReadDocumentCallback readCallback = new ReadDocumentCallback(mongoConverter, outputType, collectionName);
return execute(collectionName, new CollectionCallback>() {
@Override
- public CloseableIterator doInCollection(DBCollection collection) throws MongoException, DataAccessException {
+ public CloseableIterator doInCollection(MongoCollection collection)
+ throws MongoException, DataAccessException {
- List pipeline = (List) command.get("pipeline");
- Cursor cursor = collection.aggregate(pipeline, getNativeAggregationOptionsFromCommand(command));
+ List pipeline = (List) command.get("pipeline");
- ReadDbObjectCallback readCallback = new ReadDbObjectCallback(mongoConverter, outputType, collectionName);
+ AggregationOptions options = AggregationOptions.fromDocument(command);
- return new CloseableIterableCursorAdapter(cursor, exceptionTranslator, readCallback);
- }
+ AggregateIterable cursor = collection.aggregate(pipeline).allowDiskUse(options.isAllowDiskUse())
+ .useCursor(true);
- private AggregationOptions getNativeAggregationOptionsFromCommand(DBObject command) {
- AggregationOptions.Builder builder = AggregationOptions.builder();
- Object allowDiskUse = command.get(ALLOW_DISK_USE);
- if (allowDiskUse != null && String.valueOf(allowDiskUse).equals("true")) {
- builder.allowDiskUse(true);
+ Integer cursorBatchSize = options.getCursorBatchSize();
+ if (cursorBatchSize != null) {
+ cursor.batchSize(cursorBatchSize);
}
- return builder.build();
+
+ return new CloseableIterableCursorAdapter(cursor.iterator(), exceptionTranslator, readCallback);
}
});
}
+ /**
+ * Assert that the {@link Document} does not enable Aggregation explain mode.
+ *
+ * @param command the command {@link Document}.
+ */
+ private void assertNotExplain(Document command) {
+
+ Boolean explain = command.get("explain", Boolean.class);
+
+ if (explain != null && explain) {
+ throw new IllegalArgumentException("Can't use explain option with streaming!");
+ }
+ }
+
protected String replaceWithResourceIfNecessary(String function) {
String func = function;
@@ -2008,7 +2047,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
* @return
*/
private T executeFindOneInternal(CollectionCallback collectionCallback,
- DocumentCallback objectCallback, String collectionName) {
+ DocumentCallback objectCallback, String collectionName) {
try {
T result = objectCallback
@@ -2038,7 +2077,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
* @return
*/
private List executeFindMultiInternal(CollectionCallback> collectionCallback,
- CursorPreparer preparer, DocumentCallback objectCallback, String collectionName) {
+ CursorPreparer preparer, DocumentCallback objectCallback, String collectionName) {
try {
@@ -2242,11 +2281,10 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
* Returns all identifiers for the given documents. Will augment the given identifiers and fill in only the ones that
* are {@literal null} currently. This would've been better solved in {@link #insertDBObjectList(String, List)}
* directly but would require a signature change of that method.
- *
+ *
* @param ids
* @param documents
- * @return
- * TODO: Remove for 2.0 and change method signature of {@link #insertDBObjectList(String, List)}.
+ * @return TODO: Remove for 2.0 and change method signature of {@link #insertDBObjectList(String, List)}.
*/
private static List