I want to make the save operation efficient, so I'd like to write a bulk of objects to Mongo once in a while (i.e. when exceeding some capacity)
Would saveAll()
do that for me? Should I use BulkOperations
instead?
Short answer, yes, but only if all documents are new. If not, it will insert or update one by one.
Take a look at SimpleMongoRepository (MongoRepository's default implementation):
public <S extends T> List<S> saveAll(Iterable<S> entities) {
Assert.notNull(entities, "The given Iterable of entities not be null!");
Streamable<S> source = Streamable.of(entities);
boolean allNew = source.stream().allMatch((it) -> {
return this.entityInformation.isNew(it);
});
if (allNew) {
List<S> result = (List)source.stream().collect(Collectors.toList());
return new ArrayList(this.mongoOperations.insert(result, this.entityInformation.getCollectionName()));
} else {
return (List)source.stream().map(this::save).collect(Collectors.toList());
}
}
Notice that when all documents are new, the repository will use MongoOperations.insert method (MongoTemplate is the implementation), Then, if you look at that method's code you'll realize it does a batch insert:
public <T> Collection<T> insert(Collection<? extends T> batchToSave, String collectionName) {
Assert.notNull(batchToSave, "BatchToSave must not be null!");
Assert.notNull(collectionName, "CollectionName must not be null!");
return this.doInsertBatch(collectionName, batchToSave, this.mongoConverter);
}
UPDATE 2021:
As of spring-data-mongodb 1.9.0.RELEASE (current 3.2.2), BulkOperations comes with a lot of extra features.
If more advanced tasks are needed other than just saving a bunch of documents, then BulkOperations class is the way to go.
It covers bulk inserts, updates, and deletes:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With