7

I have been google for a while, not sure whether Spring Data MongoDB supports for bulk save.

I need to save a collection of documents into mongo as atomic, either all saved or none saved.

Can anyone share a link or some sample code for this?

1
  • 1
    There is no concept of transactions in MongoDB. Each operation is atomic but a bulk save cannot be. Commented Oct 2, 2012 at 12:14

2 Answers 2

15

When you do a save through MongoDB Java driver you can only pass a single document to MongoDB.

When you do an insert, you can pass a single element or you can pass an array of elements. The latter is what will result in a "bulk insert" (i.e. single insert command by client will result in multiple documents being inserted on the server).

However, since MongoDB does not support a notion of transaction, if one of the inserts fails there is no way to indicate that previously inserted documents should be deleted or rolled back.

For the purposes of atomicity, each document insert is a separate operation and there is no supported way to make MongoDB either insert all or none.

If this is something that your application requires there may be other ways to achieve it: - change your schema so that these are subdocuments of a single parent document (then there is technically only one "insert" of the parent document) - write the transaction semantics into your application code - use a database which natively supports two phase commit transactions.

Sign up to request clarification or add additional context in comments.

Comments

0

We have used Spring Data and Mongo Driver to achieve copying data from one database server to another.

import com.mongodb.MongoBulkWriteException;
import com.mongodb.MongoClient;
import com.mongodb.MongoException;
import com.mongodb.bulk.BulkWriteResult;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.model.BulkWriteOptions;
import com.mongodb.client.model.InsertOneModel;
import com.mongodb.client.model.WriteModel;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Component;


@Component
public class DataCopy{

public void copyData(MongoTemplate sourceMongo,MongoTemplate destinationMongo ){

Class cls = EmployeeEntity.class;
String collectionName = sourceMongo.getCollectionName(cls).get();
        MongoCollection<Document> collection = destinationMongo.getCollection(collectionName);       
Query findQuery = new Query();
        Criteria criteria = new Criteria();

        criteria.andOperator(Criteria.where("firstName").is("someName"),
                    Criteria.where("lastName").is("surname"));
        
        query.addCriteria(criteria);


    Pageable pageable = PageRequest.of(0, 10000);
        
        findQuery.with(pageable);

    List<?> pagedResult = sourceMongo.find(findQuery, cls).get()        

     
        while (!pagedResult.isEmpty()) {
            try {
                 BulkWriteResult result = collection.bulkWrite(
                        pagedResult.
                          stream().map(d -> mapWriteModel(d, destinationMongo)).collect(Collectors.toList()),
                        new BulkWriteOptions().ordered(false));
 
            }  catch (Exception e) {
                log.error("failed to copy", e);
            }

            pageable = pageable.next();
            findQuery.with(pageable);
            pagedResult = sourceMongo.find(findQuery, cls).get();

        }

 }
}

private WriteModel<? extends Document> mapWriteModel(Object obj,
                                                         MongoTemplate mongoTemplate
                                                        ) {
        Document document = new Document();
        mongoTemplate.getConverter().write(obj, document);
        return new InsertOneModel<>(document);
    }


// Code example to create mongo templates for source and target databases
MongoClient targetClient = new MongoClient("databaseUri")  
            MongoTemplate destinationMongo = new MongoTemplate(targetClient, "databaseName");

Hope this would be helpful to you.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.