lior
lior

Reputation: 1187

Spring data mongodb- copy a collection

I'm using spring data with mongodb and I would like to copy documents from one collection to another using code and not the command line. Is there a way to do this without looping over all the documents and do "insert"?

Upvotes: 2

Views: 3101

Answers (2)

Shirish Bari
Shirish Bari

Reputation: 2722

We have used Spring Data and Mongo Driver classes to copy 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.

Upvotes: 0

Artem Bilan
Artem Bilan

Reputation: 121292

There is nothing unless to use it like command like :-):

mongoTemplate.execute(new DbCallback<Object>() {

        @Override
        public Object doInDB(DB db) throws MongoException, DataAccessException {
            return db.eval("db.foo.copyTo('bar')");
        }
});

Upvotes: 3

Related Questions