I am using MongoDB in my application and was needed to insert multiple documents inside a MongoDB collection .
The version I am using is of 1.6
I saw an example here
http://docs.mongodb.org/manual/core/create/
in the
Bulk Insert Multiple Documents Section
Where the author was passing an array to do this .
When I tried the same , but why it isn't allowing , and please tell me how can I insert multiple documents at once ??
package com;
import java.util.Date;
import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.MongoClient;
public class App {
public static void main(String[] args) {
try {
MongoClient mongo = new MongoClient("localhost", 27017);
DB db = mongo.getDB("at");
DBCollection collection = db.getCollection("people");
/*
* BasicDBObject document = new BasicDBObject();
* document.put("name", "mkyong"); document.put("age", 30);
* document.put("createdDate", new Date()); table.insert(document);
*/
String[] myStringArray = new String[] { "a", "b", "c" };
collection.insert(myStringArray); // Compilation error at this line saying that "The method insert(DBObject...) in the type DBCollection is not applicable for the arguments (String[])"
} catch (Exception e) {
e.printStackTrace();
}
}
}
Please let me know what is the way so that I can insert multiple documents at once through java .
DBCollection.insert accepts a parameter of type DBObject, List<DBObject> or an array of DBObjects for inserting multiple documents at once. You are passing in a string array.
You must manually populate documents(DBObjects), insert them to a List<DBObject> or an array of DBObjects and eventually insert them.
DBObject document1 = new BasicDBObject();
document1.put("name", "Kiran");
document1.put("age", 20);
DBObject document2 = new BasicDBObject();
document2.put("name", "John");
List<DBObject> documents = new ArrayList<>();
documents.add(document1);
documents.add(document2);
collection.insert(documents);
The above snippet is essentially the same as the command you would issue in the MongoDB shell:
db.people.insert( [ {name: "Kiran", age: 20}, {name: "John"} ]);
Before 3.0, you can use below code in Java
DB db = mongoClient.getDB("yourDB");
DBCollection coll = db.getCollection("yourCollection");
BulkWriteOperation builder = coll.initializeUnorderedBulkOperation();
for(DBObject doc :yourList)
{
builder.insert(doc);
}
BulkWriteResult result = builder.execute();
return result.isAcknowledged();
If you are using mongodb version 3.0 , you can use
MongoDatabase database = mongoClient.getDatabase("yourDB");
MongoCollection<Document> collection = database.getCollection("yourCollection");
collection.insertMany(yourDocumentList);
As of MongoDB 2.6 and 2.12 version of the driver you can also now do a bulk insert operation. In Java you could use the BulkWriteOperation. An example use of this could be:
DBCollection coll = db.getCollection("user");
BulkWriteOperation bulk = coll.initializeUnorderedBulkOperation();
bulk.find(new BasicDBObject("z", 1)).upsert().update(new BasicDBObject("$inc", new BasicDBObject("y", -1)));
bulk.find(new BasicDBObject("z", 1)).upsert().update(new BasicDBObject("$inc", new BasicDBObject("y", -1)));
bulk.execute();
Creating Documents
There're two principal commands for creating documents in MongoDB:
insertOne()
insertMany()
There're other ways as well such as Update commands. We call these operations, upserts. Upserts occurs when there're no documents that match the selector used to identify documents.
Although MongoDB inserts ID by it's own, We can manually insert custom IDs as well by specifying _id parameter in the insert...() functions.
To insert multiple documents we can use insertMany() - which takes an array of documents as parameter. When executed, it returns multiple ids for each document in the array. To drop the collection, use drop() command. Sometimes, when doing bulk inserts - we may insert duplicate values. Specifically, if we try to insert duplicate _ids, we'll get the duplicate key error:
db.startup.insertMany(
[
{_id:"id1", name:"Uber"},
{_id:"id2", name:"Airbnb"},
{_id:"id1", name:"Uber"},
]
);
MongoDB stops inserting operation, if it encounters an error, to supress that - we can supply ordered:false parameter. Ex:
db.startup.insertMany(
[
{_id:"id1", name:"Uber"},
{_id:"id2", name:"Airbnb"},
{_id:"id1", name:"Airbnb"},
],
{ordered: false}
);
Your insert record format like in MongoDB that query retire from any source
EG.
{
"_id" : 1,
"name" : a
}
{
"_id" : 2,
"name" : b,
}
it is mongodb 3.0
FindIterable<Document> resulutlist = collection.find(query);
List docList = new ArrayList();
for (Document document : resulutlist) {
docList.add(document);
}
if(!docList.isEmpty()){
collectionCube.insertMany(docList);
}
Related
Suppose we have the following documents in a MongoDB collection:
{
"_id":ObjectId("562e7c594c12942f08fe4192"),
"shapes":[
{
"shape":"square",
"color":"blue"
},
{
"shape":"circle",
"color":"red"
}
]
},
{
"_id":ObjectId("562e7c594c12942f08fe4193"),
"shapes":[
{
"shape":"square",
"color":"black"
},
{
"shape":"circle",
"color":"green"
}
]
}
And the MongoDB query is
db.test.find({"shapes.color": "red"}, {_id: 0, 'shapes.$': 1});
Can someone tell me how to write it in Java?
I am using:
List<BasicDBObject> obj = new ArrayList<>();
obj1.add(new BasicDBObject("shapes.color", "red"));
List<BasicDBObject> obj1 = new ArrayList<>();
obj2.add(new BasicDBObject("shapes.$", "1"));
BasicDBObject parameters1 = new BasicDBObject();
parameters1.put("$and", obj1);
DBCursor cursor = table.find(parameters1,obj2).limit(500);
and I am not getting anything.
The syntax of the Mongo Shell find function is:
db.collection.find(query, projection)
query document Optional. Specifies selection filter using query operators. To return all documents in a collection, omit this parameter or pass an empty document ({}).
projection document Optional. Specifies the fields to return in the documents that match the query filter.
When translating this for execution by the Mongo Java driver you need to construct separate BasicDBObject instances for;
the query
the projection
Here's an example:
MongoCollection<Document> table = ...;
// {"shapes.color": "red"}
BasicDBObject query = new BasicDBObject("shapes.color", "red");
// {_id: 0, 'shapes.$': 1}
BasicDBObject projection = new BasicDBObject("shapes.$", "1").append("_id", 0);
FindIterable<Document> documents = table
// assign the query
.find(query)
// assign the projection
.projection(projection);
System.out.println(documents.first().toJson());
Given the sample documents included in your question the above code will print out:
{
"shapes": [
{
"shape": "circle",
"color": "red"
}
]
}
This is identical to the output from db.test.find({"shapes.color": "red"}, {_id: 0, 'shapes.$': 1});.
I have a device collection.
{
"_id" : "10-100-5675234",
"_type" : "Device",
"alias" : "new Alias name",
"claimCode" : "FG755DF8N",
"hardwareId" : "SERAIL02",
"isClaimed" : "true",
"model" : "VMB3010",
"userId" : "5514f428c7b93d48007ac6fd"
}
I want to search document by _id and then update it after removing a field userId from the result document. I am trying different ways but none of them is working. Please help me.
You can remove a field using $unset with mongo-java driver in this way:
MongoClient mongo = new MongoClient("localhost", 27017);
DB db = (DB) mongo.getDB("testDB");
DBCollection collection = db.getCollection("collection");
DBObject query = new BasicDBObject("_id", "10-100-5675234");
DBObject update = new BasicDBObject();
update.put("$unset", new BasicDBObject("userId",""));
WriteResult result = collection.update(query, update);
mongo.close();
The easiest way is to use the functionality in the java driver:
Query query = new Query();
query.addCriteria(Criteria.where("_id").is(new ObjectId("10-100-5675234")));
Update update = new Update();
update.unset("userId"); //the fields you want to remove
update.set("putInYourFieldHere", "putInYourValueHere"); //the fields you want to add
mongoTemplate.updateFirst(query, update, Device.class);
The above code assumes that your "_id" is your mongodb normal "_id" which means that the variable you are looking for must be encased in the new ObjectId().
Long time since this post was opened, but might be useful for someone in the future.
device.updateMany(eq("_id", "whatever"), unset("userId"));
An ugly way is to replace the old version with the new version of you document (no userid).
BasicDBObject newDocument = new BasicDBObject();
newDocument.put("_type", "Device");
newDocument.put("alias", "new Alias name");
// ...
BasicDBObject searchQuery = new BasicDBObject().append("_id", "10-100-5675234");
collection.update(searchQuery, newDocument);
The MongoDB documentation provides a clear answer to this question: use the $unset update operator.
I am using Spring Data MongoDB and would like to perform a Bulk Update just like the one described here: http://docs.mongodb.org/manual/reference/method/Bulk.find.update/#Bulk.find.update
When using regular driver it looks like this:
The following example initializes a Bulk() operations builder for the items collection, and adds various multi update operations to the list of operations.
var bulk = db.items.initializeUnorderedBulkOp();
bulk.find( { status: "D" } ).update( { $set: { status: "I", points: "0" } } );
bulk.find( { item: null } ).update( { $set: { item: "TBD" } } );
bulk.execute()
Is there any way to achieve similar result with Spring Data MongoDB ?
Bulk updates are supported from spring-data-mongodb 1.9.0.RELEASE. Here is a sample:
BulkOperations ops = template.bulkOps(BulkMode.UNORDERED, Match.class);
for (User user : users) {
Update update = new Update();
...
ops.updateOne(query(where("id").is(user.getId())), update);
}
ops.execute();
You can use this as long as the driver is current and the server you are talking to is at least MongoDB, which is required for bulk operations. Don't believe there is anything directly in spring data right now (and much the same for other higher level driver abstractions), but you can of course access the native driver collection object that implements the access to the Bulk API:
DBCollection collection = mongoOperation.getCollection("collection");
BulkWriteOperation bulk = collection.initializeOrderedBulkOperation();
bulk.find(new BasicDBObject("status","D"))
.update(new BasicDBObject(
new BasicDBObject(
"$set",new BasicDBObject(
"status", "I"
).append(
"points", 0
)
)
));
bulk.find(new BasicDBObject("item",null))
.update(new BasicDBObject(
new BasicDBObject(
"$set", new BasicDBObject("item","TBD")
)
));
BulkWriteResult writeResult = bulk.execute();
System.out.println(writeResult);
You can either fill in the DBObject types required by defining them, or use the builders supplied in the spring mongo library which should all support "extracting" the DBObject that they build.
public <T> void bulkUpdate(String collectionName, List<T> documents, Class<T> tClass) {
BulkOperations bulkOps = mongoTemplate.bulkOps(BulkOperations.BulkMode.UNORDERED, tClass, collectionName);
for (T document : documents) {
Document doc = new Document();
mongoTemplate.getConverter().write(document, doc);
org.springframework.data.mongodb.core.query.Query query = new org.springframework
.data.mongodb.core.query.Query(Criteria.where(UNDERSCORE_ID).is(doc.get(UNDERSCORE_ID)));
Document updateDoc = new Document();
updateDoc.append("$set", doc);
Update update = Update.fromDocument(updateDoc, UNDERSCORE_ID);
bulkOps.upsert(query, update);
}
bulkOps.execute();
}
Spring Mongo template is used to perform the update. The above code will work if you provide the _id field in the list of documents.
How to remove duplicate values from the result of MongoDB objects?
I have some records in my mongodb as follows
{"Filename":"PHP Book.pdf","Author":"John" ,"Description":"This is my PHP Book"}
{"Filename":"Java Book.html" ,"Author":"Paul" ,"Description":"This is my JAVA Book"}
{"Filename":".NET Book.doc" ,"Author":"James" ,"Description":"This is my .NET Book"}
below is my code to search Filename and Description fields which contains "Java" word and displaying their filenames.
Mongo m = new Mongo("10.0.0.26", 27017) ;
DB db = m.getDB("soft") ;
DBCollection col = db.getCollection("poc") ;
BasicDBObject query = new BasicDBObject();
BasicDBObject query1 = new BasicDBObject();
String KeyWord="JAVA";
query.put("Filename", java.util.regex.Pattern.compile(KeyWord));
query1.put("Content", java.util.regex.Pattern.compile(KeyWord));
DBCursor cursor = col.find(query) ;
DBCursor cursor1 = col.find(query1) ;
while (cursor.hasNext()) {
DBObject o = cursor.next();
System.out.println("File name contains JAVA:"+o.get("Filename"));
}
while (cursor1.hasNext()) {
DBObject ob = cursor1.next();
System.out.println("File name whose content contains JAVA:"+ob.get("Filename"));
}
I am getting the following output:
File Name Contains JAVA:Java Book.html
File Name whose content Contains JAVA:Java Book.html
I am getting same file name from both filename and content queries.I want to remove the duplicate values.Please suggest me.
thanks
I would suggest using a $or query, something like:
DBObject query = QueryBuilder.start().or(
new BasicDBObject("Filename", java.util.regex.Pattern.compile(KeyWord)),
new BasicDBObject("Content", java.util.regex.Pattern.compile(KeyWord))).get();
and do it as a single query instead of two separate queries.
Please be advised that MongoDB will not be able to use an index for non-anchored regular expressions. See http://docs.mongodb.org/manual/reference/operator/regex/ for details.
How can I upsert data into mongodb collection with java-driver?
I try (with empty collection):
db.getCollection(collection).update(new BasicDBObject("_id", "12"), dbobject, true, false);
But document was created with _id == ObjectID(...). Not with "12" value.
This code (js) add document with _id = "12" as expected
db.metaclass.update(
{ _id:12},
{
$set: {b:1}
},
{ upsert: true }
)
mongo-java-driver-2.11.2
If you are using mongo-java driver 3, following .updateOne() method with {upsert, true} flag works.
void setLastIndex(MongoClient mongo, Long id, Long lastIndexValue) {
Bson filter = Filters.eq("_id", id);
Bson update = new Document("$set",
new Document()
.append("lastIndex", lastIndexValue)
.append("created", new Date()));
UpdateOptions options = new UpdateOptions().upsert(true);
mongo.getDatabase(EventStreamApp.EVENTS_DB)
.getCollection(EventCursor.name)
.updateOne(filter, update, options);
}
You cannot set _id if dbobject is just a document and does not contain an update operator eg: $set, $setOnInsert.
Just passing a document will replace the whole document meaning it doesn't set an _id a falls back to ObjectId
So your example works if you use an update operator eg:
db.getCollection(collection).update(
new BasicDBObject("_id", "12"),
new BasicDBObject("$set", new BasicDBObject("Hi", "world")), true, false)
You can use the replaceOne method and specify the ReplaceOptions (since 3.7) :
private static final ReplaceOptions REPLACE_OPTIONS
= ReplaceOptions.createReplaceOptions(new UpdateOptions().upsert(true));
db.getCollection(collection).replaceOne(new BasicDBObject("_id", "12"), dbobject, REPLACE_OPTIONS);
For older versions you can directly pass the UpdateOptions to the replaceOne method :
private static final UpdateOptions UPDATE_POLICY = new UpdateOptions().upsert(true);
db.getCollection(collection).replaceOne(new BasicDBObject("_id", "12"), dbobject, UPDATE_POLICY);
As mentioned in the documentation :
replaceOne() replaces the first matching document in the collection
that matches the filter, using the replacement document.
If upsert: true and no documents match the filter, replaceOne()
creates a new document based on the replacement document.
This is to upsert with scala driver which i couldnot find in web
con.updateOne(
equal("vendor_id", vendorId),
inc("views_count", f.views),
UpdateOptions().upsert(true))
to do so import the following
import org.mongodb.scala.model.UpdateOptions