使用Mongo Shell和Java驱动程序的MongoDB upsert示例
MongoDB upsert选项与update方法一起使用,如果查询未检索到任何满足条件的文档,该方法将创建一个新文档。
此选项的默认值为false。
upsert选项根据更新参数中指定的字段和值对或者查询和更新参数中指定的字段和值对进行插入。
设置更新的Upsert选项
此操作首先搜索文档(如果不存在),然后将新文档插入数据库。
> db.car.update( ... { name: "Qualis" }, ... { ... name: "Qualis", ... speed: 50 ... }, ... { upsert: true } ... ) WriteResult({ "nMatched" : 0, "nUpserted" : 1, "nModified" : 0, "_id" : ObjectId("548d3a955a5072e76925dc1c") }) >
检查名称为Qualis的汽车是否存在,如果不存在,则将名称为" Qualis"和速度为50的文件插入数据库。
值为" 1"的nUpserted表示已插入新文档。
请注意,为避免多次插入同一文档,请在名称字段上创建索引,从而确保在每次指定的更新中,对于upsert选项仅将文档插入一次。
如果upsert由于重复的索引键错误而失败,则重试将导致更新操作成功。
Bulk.find.upsert()
upsert操作可以用于多个文档,也可以与方法update-update,updateOne和replaceOne一起使用。
upsert选项的语法是
Bulk.find(<query>).upsert().update(<update>); Bulk.find(<query>).upsert().updateOne(<update>); Bulk.find(<query>).upsert().replaceOne(<replacement>);
批量为find()方法设置Upsert选项
如果查询不满足输入参数中指定的条件,则find方法中多个文档的upsert操作将插入单个文档。
> var car = db.car.initializeUnorderedBulkOp(); > car.find( { name: "Chevrolet" } ).upsert().update( ... { ... $setOnInsert: { name: "Chevrolet",speed:55,regno:567,color: "AshBrown" }, ... $set: { cno:"H768" } ... } ... ); > car.execute(); BulkWriteResult({ "writeErrors" : [ ], "writeConcernErrors" : [ ], "nInserted" : 0, "nUpserted" : 1, "nMatched" : 0, "nModified" : 0, "nRemoved" : 0, "upserted" : [ { "index" : 0, "_id" : ObjectId("548d3b475a5072e76925dc1d") } ] }) >
此操作首先初始化并创建一个名为" car"的无序批量列表,然后在更新中使用upsert选项调用find方法。
如果不存在文档,则使用$setOnInsert标记指定插入字段和值对。
如果文档已存在,则指定$set来更新汽车的" cno"。
最后,调用批量执行方法以执行插入或者更新语句。
由于不存在该文档,因此首先进行插入,然后针对插入的记录更新cno。
批量为updateOne方法设置Upsert选项
此方法接受更新参数作为字段/键和值对。
> var car = db.car.initializeUnorderedBulkOp(); > car.find( { name: "Ferrari" } ).upsert().updateOne( ... { ... name: "Ferrari", ... speed:67, ... regno:456, ... color: "ChromeRed" ... } ... ); > car.execute(); BulkWriteResult({ "writeErrors" : [ ], "writeConcernErrors" : [ ], "nInserted" : 0, "nUpserted" : 1, "nMatched" : 0, "nModified" : 0, "nRemoved" : 0, "upserted" : [ { "index" : 0, "_id" : ObjectId("548d57525a5072e76925dc1e") } ] }) >
这将创建带有upsert选项的无序批量列表,并使用指定的字段和值对在updateOne方法中找不到时插入"法拉利"文档。
使用更新运算符为updateOne设置更新
这将使用更新运算符来设置字段的值。
$setOnInsert和$set是运算符。
> var car = db.car.initializeUnorderedBulkOp(); > car.find( { speed:67,regno:768} ).upsert().updateOne( ... { ... $setOnInsert: { name:"Audi"}, ... $set: { speed: 89 } ... } ... ); > car.execute(); BulkWriteResult({ "writeErrors" : [ ], "writeConcernErrors" : [ ], "nInserted" : 0, "nUpserted" : 1, "nMatched" : 0, "nModified" : 0, "nRemoved" : 0, "upserted" : [ { "index" : 0, "_id" : ObjectId("548d57b35a5072e76925dc1f") } ] }) >
名称的值使用$setonInsert设置,而更新使用$set运算符完成。
批量为replaceOne方法设置Upsert选项
这将使用replaceOne方法执行插入操作,方法是仅接受字段和值对作为参数。
> var car = db.car.initializeUnorderedBulkOp(); > car.find( { name: "Skoda" } ).upsert().replaceOne( ... { ... name: "Skoda", ... cno: "H7865", ... speed: 80, ... } ... ); > car.execute(); BulkWriteResult({ "writeErrors" : [ ], "writeConcernErrors" : [ ], "nInserted" : 0, "nUpserted" : 1, "nMatched" : 0, "nModified" : 0, "nRemoved" : 0, "upserted" : [ { "index" : 0, "_id" : ObjectId("548d58205a5072e76925dc20") } ] }) >
这将执行文档插入,并且此插入的文档是替换文档。
用于MongoDB的Java程序upsert
在本节中,我们将编写一个Java程序来处理带有update,updateOne和replaceOne方法的upsert选项。
package com.theitroad.mongodb; import com.mongodb.BasicDBObject; import com.mongodb.BulkWriteOperation; import com.mongodb.DB; import com.mongodb.DBCollection; import com.mongodb.DBCursor; import com.mongodb.MongoClient; import com.mongodb.WriteResult; import java.net.UnknownHostException; public class MongoDBUpsert { public static void upsertTrue() throws UnknownHostException { MongoClient m1 = new MongoClient("localhost"); DB db = m1.getDB("test"); DBCollection coll = db.getCollection("car"); BasicDBObject o1 = new BasicDBObject(); o1.append("$set", new BasicDBObject("name", "Innova")); BasicDBObject query = new BasicDBObject().append("speed", 56); WriteResult c1 = coll.update(query, o1, true, false); DBCursor carcursor = coll.find(); try { while (carcursor.hasNext()) { System.out.println(carcursor.next()); } } finally { carcursor.close(); } } public static void upsertBulkUnorderedDocsForUpdate() throws UnknownHostException { //Get a new connection to the db assuming that it is running MongoClient mongoClient = new MongoClient("localhost"); ////use test as a datbase,use your database here DB db = mongoClient.getDB("test"); ////fetch the collection object ,car is used here,use your own DBCollection coll = db.getCollection("car"); //intialize and create a unordered bulk BulkWriteOperation b1 = coll.initializeUnorderedBulkOperation(); BasicDBObject o1 = new BasicDBObject(); o1.append("$setOnInsert", new BasicDBObject("name", "innova").append("speed", 54)); o1.append("$set", new BasicDBObject("cno", "H456")); b1.find(new BasicDBObject("name", "Zen")).upsert().update(o1); b1.execute(); DBCursor c1 = coll.find(); System.out.println("---------------------------------"); try { while (c1.hasNext()) { System.out.println(c1.next()); } } finally { c1.close(); } } public static void upsertBulkUnordereDocsForUpdateOne() throws UnknownHostException { //Get a new connection to the db assuming that it is running MongoClient mongoClient = new MongoClient("localhost"); //use test as a database,use your database here DB db = mongoClient.getDB("test"); //fetch the collection object ,car is used here,use your own DBCollection coll = db.getCollection("car"); //intialize and create a unordered bulk BulkWriteOperation b1 = coll.initializeUnorderedBulkOperation(); BasicDBObject o1 = new BasicDBObject(); o1.append( "$setOnInsert", new BasicDBObject("name", "Xylo").append("speed", 67).append( "cno", "H654")); b1.find(new BasicDBObject("name", "Xylo")).upsert().updateOne(o1); b1.execute(); DBCursor c1 = coll.find(); System.out.println("---------------------------------"); try { while (c1.hasNext()) { System.out.println(c1.next()); } } finally { c1.close(); } } public static void upsertBulkForUpdateOneWithOperators() throws UnknownHostException { //Get a new connection to the db assuming that it is running MongoClient mongoClient = new MongoClient("localhost"); ////use test as a datbase,use your database here DB db = mongoClient.getDB("test"); ////fetch the collection object ,car is used here,use your own DBCollection coll = db.getCollection("car"); //intialize and create a unordered bulk BulkWriteOperation b1 = coll.initializeOrderedBulkOperation(); BasicDBObject o1 = new BasicDBObject(); //insert if document not found and set the fields with updated value o1.append("$setOnInsert", new BasicDBObject("cno", "H123")); o1.append("$set", new BasicDBObject("speed", "63")); b1.find(new BasicDBObject("name", "Santro").append("speed", 654)) .upsert().updateOne(o1); b1.execute(); DBCursor c1 = coll.find(); System.out.println("---------------------------------"); try { while (c1.hasNext()) { System.out.println(c1.next()); } } finally { c1.close(); } } public static void upsertBulkUnorderedDocsForReplaceOne() throws UnknownHostException { //Get a new connection to the db assuming that it is running MongoClient mongoClient = new MongoClient("localhost"); ////use test as a datbase,use your database here DB db = mongoClient.getDB("test"); //fetch the collection object ,car is used here,use your own DBCollection coll = db.getCollection("car"); //intialize and create a unordered bulk BulkWriteOperation b1 = coll.initializeOrderedBulkOperation(); //insert query BasicDBObject o1 = new BasicDBObject("name", "Qualis").append("speed", 76).append("color", "Palebrown"); b1.find(new BasicDBObject("name", "Qualis")).upsert().replaceOne(o1); b1.execute(); DBCursor c1 = coll.find(); System.out.println("---------------------------------"); try { while (c1.hasNext()) { System.out.println(c1.next()); } } finally { c1.close(); } } public static void main(String[] args) throws UnknownHostException { //invoke all the methods upsertTrue(); upsertBulkUnorderedDocsForUpdate(); upsertBulkUnordereDocsForUpdateOne(); upsertBulkForUpdateOneWithOperators(); upsertBulkUnorderedDocsForReplaceOne(); } }
对不存在的集合执行上述程序时,将产生以下结果。
{ "_id" : { "$oid" : "548d59285a5072e76925dc25"} , "speed" : 56 , "name" : "Innova"} -------------------------------- { "_id" : { "$oid" : "548d59285a5072e76925dc25"} , "speed" : 56 , "name" : "Innova"} { "_id" : { "$oid" : "548d59285a5072e76925dc26"} , "name" : "innova" , "speed" : 54 , "cno" : "H456"} -------------------------------- { "_id" : { "$oid" : "548d59285a5072e76925dc25"} , "speed" : 56 , "name" : "Innova"} { "_id" : { "$oid" : "548d59285a5072e76925dc26"} , "name" : "innova" , "speed" : 54 , "cno" : "H456"} { "_id" : { "$oid" : "548d59285a5072e76925dc27"} , "name" : "Xylo" , "speed" : 67 , "cno" : "H654"} -------------------------------- { "_id" : { "$oid" : "548d59285a5072e76925dc25"} , "speed" : 56 , "name" : "Innova"} { "_id" : { "$oid" : "548d59285a5072e76925dc26"} , "name" : "innova" , "speed" : 54 , "cno" : "H456"} { "_id" : { "$oid" : "548d59285a5072e76925dc27"} , "name" : "Xylo" , "speed" : 67 , "cno" : "H654"} { "_id" : { "$oid" : "548d59285a5072e76925dc28"} , "name" : "Santro" , "speed" : "63" , "cno" : "H123"} -------------------------------- { "_id" : { "$oid" : "548d59285a5072e76925dc25"} , "speed" : 56 , "name" : "Innova"} { "_id" : { "$oid" : "548d59285a5072e76925dc26"} , "name" : "innova" , "speed" : 54 , "cno" : "H456"} { "_id" : { "$oid" : "548d59285a5072e76925dc27"} , "name" : "Xylo" , "speed" : 67 , "cno" : "H654"} { "_id" : { "$oid" : "548d59285a5072e76925dc28"} , "name" : "Santro" , "speed" : "63" , "cno" : "H123"} { "_id" : { "$oid" : "548d59285a5072e76925dc29"} , "name" : "Qualis" , "speed" : 76 , "color" : "Palebrown"}