Skip to content

Adding support for InsertManyOptions for insert and insertAll methods #4273

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
import com.mongodb.ReadPreference;
import com.mongodb.client.ClientSession;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.model.InsertManyOptions;
import com.mongodb.client.result.DeleteResult;
import com.mongodb.client.result.UpdateResult;

Expand All @@ -71,6 +72,7 @@
* @author Thomas Darimont
* @author Maninder Singh
* @author Mark Paluch
* @author Tomasz Forys
*/
public interface MongoOperations extends FluentMongoOperations {

Expand Down Expand Up @@ -1371,6 +1373,19 @@ default long exactCount(Query query, String collectionName) {
<T> Collection<T> insert(Collection<? extends T> batchToSave, Class<?> entityClass);

/**
* Insert a Collection of objects into a collection in a single batch write to the database with additional
* insert options.
*
* @param batchToSave the batch of objects to save. Must not be {@literal null}.
* @param entityClass class that determines the collection to use. Must not be {@literal null}.
* @param options options for insert many operation. Must not be {@literal null}.
* @return the inserted objects that.
* @throws org.springframework.data.mapping.MappingException if the target collection name cannot be
* {@link #getCollectionName(Class) derived} from the given type.
*/
<T> Collection<T> insert(Collection<? extends T> batchToSave, Class<?> entityClass, InsertManyOptions options);

/**
* Insert a batch of objects into the specified collection in a single batch write to the database.
*
* @param batchToSave the list of objects to save. Must not be {@literal null}.
Expand All @@ -1379,6 +1394,17 @@ default long exactCount(Query query, String collectionName) {
*/
<T> Collection<T> insert(Collection<? extends T> batchToSave, String collectionName);

/**
* Insert a batch of objects into the specified collection in a single batch write to the database with additional
* insert options.
*
* @param batchToSave the list of objects to save. Must not be {@literal null}.
* @param collectionName name of the collection to store the object in. Must not be {@literal null}.
* @param options options for insert many operation. Must not be {@literal null}.
* @return the inserted objects that.
*/
<T> Collection<T> insert(Collection<? extends T> batchToSave, String collectionName, InsertManyOptions options);

/**
* Insert a mixed Collection of objects into a database collection determining the collection name to use based on the
* class.
Expand All @@ -1390,6 +1416,18 @@ default long exactCount(Query query, String collectionName) {
*/
<T> Collection<T> insertAll(Collection<? extends T> objectsToSave);

/**
* Insert a mixed Collection of objects into a database collection determining the collection name to use based on the
* class with additional insert options.
*
* @param objectsToSave the list of objects to save. Must not be {@literal null}.
* @param options options for insert many operation. Must not be {@literal null}.
* @return the inserted objects.
* @throws org.springframework.data.mapping.MappingException if the target collection name cannot be
* {@link #getCollectionName(Class) derived} for the given objects.
*/
<T> Collection<T> insertAll(Collection<? extends T> objectsToSave, InsertManyOptions options);

/**
* Save the object to the collection for the entity type of the object to save. This will perform an insert if the
* object is not already present, that is an 'upsert'. <br />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@
* @author Anton Barkan
* @author Bartłomiej Mazur
* @author Michael Krog
* @author Tomasz Forys
*/
public class MongoTemplate implements MongoOperations, ApplicationContextAware, IndexOperationsProvider {

Expand Down Expand Up @@ -1234,34 +1235,44 @@ protected <T> T doInsert(String collectionName, T objectToSave, MongoWriter<T> w
}

@Override
@SuppressWarnings("unchecked")
public <T> Collection<T> insert(Collection<? extends T> batchToSave, Class<?> entityClass) {
return insert(batchToSave, getCollectionName(entityClass));
}

Assert.notNull(batchToSave, "BatchToSave must not be null");
@Override
public <T> Collection<T> insert(Collection<? extends T> batchToSave, Class<?> entityClass, InsertManyOptions options) {
return insert(batchToSave, getCollectionName(entityClass), options);
}

return (Collection<T>) doInsertBatch(getCollectionName(entityClass), batchToSave, this.mongoConverter);
@Override
public <T> Collection<T> insert(Collection<? extends T> batchToSave, String collectionName) {
return insert(batchToSave, collectionName, new InsertManyOptions());
}

@Override
@SuppressWarnings("unchecked")
public <T> Collection<T> insert(Collection<? extends T> batchToSave, String collectionName) {
public <T> Collection<T> insert(Collection<? extends T> batchToSave, String collectionName, InsertManyOptions options) {

Assert.notNull(batchToSave, "BatchToSave must not be null");
Assert.notNull(collectionName, "CollectionName must not be null");

return (Collection<T>) doInsertBatch(collectionName, batchToSave, this.mongoConverter);
return (Collection<T>) doInsertBatch(collectionName, batchToSave, this.mongoConverter, options);
}

@Override
@SuppressWarnings("unchecked")
public <T> Collection<T> insertAll(Collection<? extends T> objectsToSave) {
return insertAll(objectsToSave, new InsertManyOptions());
}

@Override
@SuppressWarnings("unchecked")
public <T> Collection<T> insertAll(Collection<? extends T> objectsToSave, InsertManyOptions options) {

Assert.notNull(objectsToSave, "ObjectsToSave must not be null");
return (Collection<T>) doInsertAll(objectsToSave, this.mongoConverter);
return (Collection<T>) doInsertAll(objectsToSave, this.mongoConverter, options);
}

@SuppressWarnings("unchecked")
protected <T> Collection<T> doInsertAll(Collection<? extends T> listToSave, MongoWriter<T> writer) {
protected <T> Collection<T> doInsertAll(Collection<? extends T> listToSave, MongoWriter<T> writer, InsertManyOptions options) {

Map<String, List<T>> elementsByCollection = new HashMap<>();
List<T> savedObjects = new ArrayList<>(listToSave.size());
Expand All @@ -1273,27 +1284,22 @@ protected <T> Collection<T> doInsertAll(Collection<? extends T> listToSave, Mong
}

String collection = getCollectionName(ClassUtils.getUserClass(element));
List<T> collectionElements = elementsByCollection.get(collection);

if (null == collectionElements) {
collectionElements = new ArrayList<>();
elementsByCollection.put(collection, collectionElements);
}

List<T> collectionElements = elementsByCollection.computeIfAbsent(collection, k -> new ArrayList<>());
collectionElements.add(element);
}

for (Map.Entry<String, List<T>> entry : elementsByCollection.entrySet()) {
savedObjects.addAll((Collection<T>) doInsertBatch(entry.getKey(), entry.getValue(), this.mongoConverter));
savedObjects.addAll(doInsertBatch(entry.getKey(), entry.getValue(), writer, options));
}

return savedObjects;
}

protected <T> Collection<T> doInsertBatch(String collectionName, Collection<? extends T> batchToSave,
MongoWriter<T> writer) {
MongoWriter<T> writer, InsertManyOptions options) {

Assert.notNull(writer, "MongoWriter must not be null");
Assert.notNull(options, "InsertManyOptions must not be null");

List<Document> documentList = new ArrayList<>(batchToSave.size());
List<T> initializedBatchToSave = new ArrayList<>(batchToSave.size());
Expand All @@ -1315,7 +1321,7 @@ protected <T> Collection<T> doInsertBatch(String collectionName, Collection<? ex
initializedBatchToSave.add(initialized);
}

List<Object> ids = insertDocumentList(collectionName, documentList);
List<Object> ids = insertDocumentList(collectionName, documentList, options);
List<T> savedObjects = new ArrayList<>(documentList.size());

int i = 0;
Expand Down Expand Up @@ -1445,7 +1451,7 @@ protected Object insertDocument(String collectionName, Document document, Class<
});
}

protected List<Object> insertDocumentList(String collectionName, List<Document> documents) {
protected List<Object> insertDocumentList(String collectionName, List<Document> documents, InsertManyOptions options) {

if (documents.isEmpty()) {
return Collections.emptyList();
Expand All @@ -1462,9 +1468,9 @@ protected List<Object> insertDocumentList(String collectionName, List<Document>
WriteConcern writeConcernToUse = prepareWriteConcern(mongoAction);

if (writeConcernToUse == null) {
collection.insertMany(documents);
collection.insertMany(documents, options);
} else {
collection.withWriteConcern(writeConcernToUse).insertMany(documents);
collection.withWriteConcern(writeConcernToUse).insertMany(documents, options);
}

return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@

import com.mongodb.ClientSessionOptions;
import com.mongodb.ReadPreference;
import com.mongodb.client.model.InsertManyOptions;
import com.mongodb.client.result.DeleteResult;
import com.mongodb.client.result.UpdateResult;
import com.mongodb.reactivestreams.client.ClientSession;
Expand All @@ -68,6 +69,7 @@
* @author Mark Paluch
* @author Christoph Strobl
* @author Mathieu Ouellet
* @author Tomasz Forys
* @since 2.0
* @see Flux
* @see Mono
Expand Down Expand Up @@ -1146,6 +1148,16 @@ default Mono<Long> exactCount(Query query, String collectionName) {
*/
<T> Flux<T> insert(Collection<? extends T> batchToSave, String collectionName);

/**
* Insert a batch of objects into the specified collection in a single batch write to the database with additional
* insert options.
*
* @param batchToSave the list of objects to save. Must not be {@literal null}.
* @param collectionName name of the collection to store the object in. Must not be {@literal null}.
* @param options options for insert many operation. Must not be {@literal null}.
* @return the inserted objects.
*/
<T> Flux<T> insert(Collection<? extends T> batchToSave, String collectionName, InsertManyOptions options);
/**
* Insert a mixed Collection of objects into a database collection determining the collection name to use based on the
* class.
Expand All @@ -1157,6 +1169,52 @@ default Mono<Long> exactCount(Query query, String collectionName) {
*/
<T> Flux<T> insertAll(Collection<? extends T> objectsToSave);

/**
* Insert a mixed Collection of objects into a database collection determining the collection name to use based on the
* class with additional insert options.
*
* @param objectsToSave the list of objects to save. Must not be {@literal null}.
* @param options options for insert many operation. Must not be {@literal null}.
* @return the saved objects.
* @throws org.springframework.data.mapping.MappingException if the target collection name cannot be
* {@link #getCollectionName(Class) derived} for the given objects.
*/
<T> Flux<T> insertAll(Collection<? extends T> objectsToSave, InsertManyOptions options);

/**
* Insert a mixed Collection of objects into a database collection determining the collection name to use based on the
* class with additional insert options.
*
* @param objectsToSave the publisher which provides objects to save. Must not be {@literal null}.
* @param options options for insert many operation. Must not be {@literal null}.
* @return the inserted objects.
*/
<T> Flux<T> insertAll(Mono<? extends Collection<? extends T>> objectsToSave, InsertManyOptions options);

/**
* Insert a Collection of objects into a collection in a single batch write to the database with additional
* insert options.
*
* @param batchToSave the publisher which provides objects to save. Must not be {@literal null}.
* @param entityClass class that determines the collection to use. Must not be {@literal null}.
* @param options options for insert many operation. Must not be {@literal null}.
* @return the inserted objects.
* @throws org.springframework.data.mapping.MappingException if the target collection name cannot be
* {@link #getCollectionName(Class) derived} for the type.
*/
<T> Flux<T> insertAll(Mono<? extends Collection<? extends T>> batchToSave, Class<?> entityClass, InsertManyOptions options);

/**
* Insert objects into the specified collection in a single batch write to the database with additional insert
* options.
*
* @param batchToSave the publisher which provides objects to save. Must not be {@literal null}.
* @param collectionName name of the collection to store the object in. Must not be {@literal null}.
* @param options options for insert many operation. Must not be {@literal null}.
* @return the inserted objects.
*/
<T> Flux<T> insertAll(Mono<? extends Collection<? extends T>> batchToSave, String collectionName, InsertManyOptions options);

/**
* Insert the object into the collection for the entity type of the object to save. <br />
* The object is converted to the MongoDB native representation using an instance of {@see MongoConverter}. <br />
Expand Down
Loading