Copying a mongo collection using Java Driver - mongodb

I want to copy the contents from one collection to another.
in mongod this can be done:
db.tempMongoItem.find().forEach( function(x){db.mongoItem.insert(x)} )
Using Java Mongo Driver, I try:
DB db = mongoClient.getDB("mydb")
CommandResult result = db.command("db.tempMongoItem.find().forEach( function(x){db.mongoItem.insert(x)} )")
But I get:
result = [serverUsed:localhost:27017, ok:0.0, errmsg:no such cmd: db.tempMongoItem.find().forEach( function(x){db.mongoItem.insert(x)} ), code:59, bad cmd:[db.tempMongoItem.find().forEach( function(x){db.mongoItem.insert(x)} ):true]]
Any ideas?

You need to emulate the same thing JS is doing in Java, which means getting a cursor and iterating over it, inserting each document into new collection.
Something like this (coll is current, coll2 is new collection):
DBCursor cursor = coll.find();
try {
while(cursor.hasNext()) {
coll2.insert(cursor.next());
}
} finally {
cursor.close();
}
Both coll and coll2 are assumed to be DBCollection type.
Since it appears you are copying within the same DB, there is another way to do this if you are using 2.6 MongoDB using aggregation framework $out stage:
db.collection.aggregate({"$out":"newCollection"});
Note that this is limited to outputting into the same DB that original collection is in.

The following JAVA code will copy the collection from source to destination for a given database name (using mongodb-driver 3.0.4)
/** Clone a collection.
*
* #param fromCollectionName - The name of collection to be cloned
* #param toCollectionName - The name of the cloned collection
* #param dbName - The name of the database
*/
public void cloneCollection(String fromCollectionName, String toCollectionName, String dbName) throws MongoException {
MongoCollection toCol = this.getCollection(toCollectionName, dbName);
if (toCol != null) {
throw new MongoException("The destination collection already exists.");
}
List<Document> ops = new ArrayList<>();
ops.add(new Document("$out",toCollectionName));
MongoCollection sourceCollection = this.getCollection(fromCollectionName, dbName);
sourceCollection.aggregate(ops);
}
public MongoCollection getCollection(String collection, String dbName) {
MongoClient mongo = new MongoClient(new ServerAddress("localhost", Integer.parseInt(port)));
MongoDatabase database = mongo.getDatabase(dbName);
return curdb.getCollection(collection);
}
Please note that this will not copy over the indices that you have created in source collection. You will have to copy the indices seperately

Following up on Asya's response, you can use Java 8 Lambda functions to do:
collSource.find().forEach((Block<Document>) collTarget::insertOne);

Related

how to get all the documents in collection from mongoDB using spring

I was trying to get all the documents from a collection in mongoDB , I am using spring.
MongoTemplate mongoOperation = SpringMongoConfig1.mongoTemplate()
Here in monngoOperation I did not find any method which returns all the docs from a collection .
can anyone help in this ?
If you want to find all the documents of JavaDocumentName(any collection name in java)
List<JavaDocumentName> listRes = mongoOperation.findAll(JavaDocumentName.class);
You can do like this:
//If you don't need connection's configures. i.e. your mongo is in you localhost at 127.0.0.1:27017
MongoClient cliente = new MongoClient(); //to connect into a mongo DB
MongoDatabase mongoDb = client.getDatabase("DBname"); //get database, where DBname is the name of your database
MongoCollection<Document> robosCollection = mongoDb.getCollection("collectionName"); //get the name of the collection that you want
MongoCursor<Document> cursor = robosCollection.find().cursor();//Mongo Cursor interface implementing the iterator protocol
cursor.forEachRemaining(System.out::println); //print all documents in Collection using method reference

Using GET to return data in MongoDB

I am trying to connect to MongoDB with Web Api, trying to return the connected data in MongoDB using Get. The name of the database is "test" and the collection name is "restaurant".
Here is the code I have
public IEnumerable<restaurants> Get()
{
var client = new MongoClient();
var dbs = client.GetDatabase("test");
var collection = dbs.GetCollection<restaurants>("restaurants");
return collection;
}
The last collection word is underlined, and I have not found what needs to be returned (in place of collection) in order to show the database in MongoDB (using postman).
I think you are trying to return IMongoCollection, not IEnumerable so last line is underlined :)
Try to transform collection to List (asynchronously), then return. For example:
public Task<List<restaurants>> GetRestaurantsAsync()
{
var client = new MongoClient();
var dbs = client.GetDatabase("test");
var collection = dbs.GetCollection<restaurants>("restaurants");
return await collection.Find(_ => true).ToListAsync();
}
public async Task MainAsync()
{
List<restaurants> restaurantsList = await GetRestaurantsAsync();
}
Note: it depends on which version of mongo c# driver you're using.

Mongo DB : Is it possible to know how many Database calls are made to the Mongo DB?

This is my java class that will connect to Mongo DB and fetch the Data .
public class Test
{
public static void main(String args[])
{
DBCursor cursor = null;
DBCollection coll = null;
BasicDBObject query = new BasicDBObject();
String symbol = args[0];
query.put("symbol", "" + symbol);
cursor = coll.find(query);
int count = coll.find(query).count();
}
}
My question is , is it possible to know how many queries are made to the Mongo DB through this program ??
What i want to know is that whether two calls are made to the Mongo DB with this below statements
cursor = coll.find(query);
int count = coll.find(query).count();
Is it possible to know if two calls are amde to the Mongo DB with the above ??
You can use the MongoDB profiling to see the queries that are executed against the server. See the MongoDB documentation for further information: http://docs.mongodb.org/manual/reference/method/db.setProfilingLevel/
In short words: Execute db.setProfilingLevel(2) in your shell and look into the system.profile collection on your server.
If that is the only program connecting to MongoDB you can turn on profiling: http://docs.mongodb.org/manual/tutorial/manage-the-database-profiler/
You would turn profiling upto its max level (2), however if this is just one application of many then there might be (as in PHP) a MongoLog class ( http://php.net/manual/en/class.mongolog.php ) you could use.

using findAndModify in mongodb using grails gorm

I need to use findAndModify in my application with grails and mongoDB.
I used this code :
public static String getNextId(DB db, String seq_name) {
String sequence_collection = "seq"; // the name of the sequence collection
String sequence_field = "seq"; // the name of the field which holds the sequence
DBCollection seq = db.getCollection(sequence_collection); // get the collection (this will create it if needed)
// this object represents your "query", its analogous to a WHERE clause in SQL
DBObject query = new BasicDBObject();
query.put("_id", seq_name); // where _id = the input sequence name
// this object represents the "update" or the SET blah=blah in SQL
DBObject change = new BasicDBObject(sequence_field, 1);
DBObject update = new BasicDBObject("$inc", change); // the $inc here is a mongodb command for increment
// Atomically updates the sequence field and returns the value for you
DBObject res = seq.findAndModify(query, new BasicDBObject(), new BasicDBObject(), false, update, true, true);
return res.get(sequence_field).toString();
}
and it work successful. But now I want use findAndModify without native mongodb object, and with using GORM.
Is there any solution for this work?
There is not way to accomplish this without native API, you can however write your code a bit more compact like this:
def collection = Seq.collection
collection.findAndModify([_id: seq_name ], [ "\$inc": [seq:1] ])
Config your DataSource.groovy with db configurations.
Then define a Domain class:
Class Seq{
int seq
}
And use dynamic finder in a sevice:
Class SeqService {
String findAndModify(String seq_name) {
def seqInstance = Seq.get(seq_name)
if(seqInstance){
seqInstance.seq ++
seqInstance.save()
return seqInstance.seq.toString()
}
return '' //instance not found
}
}
Then make a call when you need that action:
def seqService
def id
.......
def result = seqService.findAndModify(id)
....

Capped collections using MongoDB and SpringData

I am trying to create a capped collection for logging using mongoTemplate. However my collection size is growing beyond the size I passed as arguments. Can anyone please help with this.
public synchronized MongoTemplate getTemplate() {
if (template == null) {
Mongo mongo = null;
mongo = new Mongo(addrs);
template = new MongoTemplate(mongo, this.dbName);
if(!template.collectionExists(HttpRequestEntity.class)){
CollectionOptions options = new CollectionOptions(4,4,true);
template.createCollection(HttpRequestEntity.class, options);
}
}
return template;
}
For saving I am calling save on this template instance
getTemplate().save(entity);
Got it working after I deleted the collection from mongo console. I guess it was use old meta data as template.collectionExists(HttpRequestEntity.class) was returning true.