MongoDB插入
今天,我们将研究MongoDB插入命令。
Mongo Client可用于将文档插入集合中。
我们还可以插入一系列文档,今天我们将研究与MongoDB插入相关的各种操作。
MongoDB插入
对于MongoDB插入示例,我使用的是MongoDB版本3.4.7和Java驱动程序版本3.5.0。
但是,这些也应与其他版本一起使用。
请注意,mongo Java驱动程序API在3.x版本中已完全更改,因此,如果您使用的是旧版2.x版本,则必须相应地修改代码。
使用Mongo Client插入MongoDB
这是一个简单的示例,其中我将一个文档插入Person集合。
hyman:mongodb hyman$mongo MongoDB shell version v3.4.7 connecting to: mongodb://127.0.0.1:27017 MongoDB server version: 3.4.7 Welcome to the MongoDB shell. For interactive help, type "help". > use theitroad switched to db theitroad > show collections > db.Persons.insert({name:"hyman",country:"San Franceco"}) WriteResult({ "nInserted" : 1 }) > show collections Persons > db.Persons.find() { "_id" : ObjectId("59a3d6bf03ca62436260d57a"), "name" : "hyman", "country" : "San Franceco" } >
请注意,如果我们不提供主键(即_id),MongoDB会自动生成它,并将其存储为ObjectId对象。
还要检查它是否返回包含写入文档数的" WriteResult"对象。
如果该集合不存在,MongoDB将创建它。
用主键插入MongoDB
现在,我们提供mongodb文档的主键,并查看可能发生的不同情况。
MongoDB插入具有ID的单个文档
> db.Persons.insert({_id:123,name:"hyman",country:"San Franceco"}) WriteResult({ "nInserted" : 1 }) > db.Persons.find() { "_id" : ObjectId("53fc3dc9b1e38e3716f79113"), "name" : "hyman", "country" : "San Franceco" } { "_id" : 123, "name" : "hyman", "country" : "San Franceco" } >
如果已经存储了提供的ID的对象该怎么办。
MongoDB插入文档重复键错误
> db.Persons.insert({_id:123,name:"David",country:"San Franceco"}) WriteResult({ "nInserted" : 0, "writeError" : { "code" : 11000, "errmsg" : "insertDocument :: caused by :: 11000 E11000 duplicate key error index: theitroad.Persons.$_id_ dup key: { : 123.0 }" } }) >
好了,从输出看来,WriteResult还提供了错误代码和与之相关的消息,请注意,插入的行返回为0。
MongoDB批量插入
现在,让我们尝试使用一个命令插入多个文档。
> db.Persons.insert([{name:"David"},{name:"Kumar"}]) BulkWriteResult({ "writeErrors" : [ ], "writeConcernErrors" : [ ], "nInserted" : 2, "nUpserted" : 0, "nMatched" : 0, "nModified" : 0, "nRemoved" : 0, "upserted" : [ ] }) >
因此,对于一系列文档,MongoDB插入操作将返回包含更多信息的" BulkWriteResult"。
让我们尝试插入ID为ID的文档数组。
> db.Persons.insert([{_id:100,name:"David"},{_id:101,name:"Kumar"}]) BulkWriteResult({ "writeErrors" : [ ], "writeConcernErrors" : [ ], "nInserted" : 2, "nUpserted" : 0, "nMatched" : 0, "nModified" : 0, "nRemoved" : 0, "upserted" : [ ] }) >
现在,让我们看看在数组中插入一个文档出错时会发生什么。
> db.Persons.insert( ... [{_id:102,name:"PK"}, ... {_id:101,name:"Kumar"}, ... {_id:103,name:"PK"}]) BulkWriteResult({ "writeErrors" : [ { "index" : 1, "code" : 11000, "errmsg" : "insertDocument :: caused by :: 11000 E11000 duplicate key error index: theitroad.Persons.$_id_ dup key: { : 101.0 }", "op" : { "_id" : 101, "name" : "Kumar" } } ], "writeConcernErrors" : [ ], "nInserted" : 1, "nUpserted" : 0, "nMatched" : 0, "nModified" : 0, "nRemoved" : 0, "upserted" : [ ] }) > db.Persons.find() { "_id" : ObjectId("53fc3dc9b1e38e3716f79113"), "name" : "hyman", "country" : "San Franceco" } { "_id" : 123, "name" : "hyman", "country" : "San Franceco" } { "_id" : ObjectId("53fc40d1b1e38e3716f79114"), "name" : "David" } { "_id" : ObjectId("53fc40d1b1e38e3716f79115"), "name" : "Kumar" } { "_id" : 100, "name" : "David" } { "_id" : 101, "name" : "Kumar" } { "_id" : 102, "name" : "PK" } >
很明显,当任何文档插入失败,未插入任何其他记录时,操作将终止,并且我们会收到错误消息,清楚地表明是哪个记录引起了问题。
MongoDB大容量插入排序和writeConcern参数
如果我们要执行批量操作并希望稍后处理错误文档,可以使用ordered
参数告诉MongoDB跳过错误文档该怎么办。
> db.Persons.insert( [{_id:102,name:"PK"}, {_id:101,name:"Kumar"}, {_id:103,name:"PK"}] ,{ordered:false}) BulkWriteResult({ "writeErrors" : [ { "index" : 0, "code" : 11000, "errmsg" : "insertDocument :: caused by :: 11000 E11000 duplicate key error index: theitroad.Persons.$_id_ dup key: { : 102.0 }", "op" : { "_id" : 102, "name" : "PK" } }, { "index" : 1, "code" : 11000, "errmsg" : "insertDocument :: caused by :: 11000 E11000 duplicate key error index: theitroad.Persons.$_id_ dup key: { : 101.0 }", "op" : { "_id" : 101, "name" : "Kumar" } } ], "writeConcernErrors" : [ ], "nInserted" : 1, "nUpserted" : 0, "nMatched" : 0, "nModified" : 0, "nRemoved" : 0, "upserted" : [ ] }) > db.Persons.find() { "_id" : ObjectId("53fc3dc9b1e38e3716f79113"), "name" : "hyman", "country" : "San Franceco" } { "_id" : 123, "name" : "hyman", "country" : "San Franceco" } { "_id" : ObjectId("53fc40d1b1e38e3716f79114"), "name" : "David" } { "_id" : ObjectId("53fc40d1b1e38e3716f79115"), "name" : "Kumar" } { "_id" : 100, "name" : "David" } { "_id" : 101, "name" : "Kumar" } { "_id" : 102, "name" : "PK" } { "_id" : 103, "name" : "PK" } >
类似地,我们也可以为不同级别的关注点传递writeConcern
参数,默认的写关注点被确认。
我们将在以后的文章中进行研究。
MongoDB插入Java示例
现在,让我们看看使用Java驱动程序在MongoDB集合中执行插入操作的不同方法。
请注意,这些Java程序使用的是mongo-java-driver版本3.5.0。
- MongoDB插入单个文档的示例
一个简单的程序,使用MongoCollection.insertOne
方法插入单个文档。
package com.theitroad.mongodb.main; import java.net.UnknownHostException; import org.bson.Document; import com.mongodb.MongoClient; import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoDatabase; public class MongoDBInsertExample { public static void main(String[] args) throws UnknownHostException { MongoClient mongo = new MongoClient("localhost", 27017); MongoDatabase db = mongo.getDatabase("theitroad"); MongoCollection<Document> col = db.getCollection("Persons"); Document document = new Document(); document.append("name", "hyman"); document.append("country", "USA"); col.insertOne(document); System.out.println("ID Generated=" + document.getObjectId("_id").toString()); mongo.close(); } }
下图显示了生成的输出,请注意生成的ID正在打印到控制台。
我们还可以像下面那样传递我们自己的id参数。
document.append("_id",new ObjectId("123456789012".getBytes())); //min byte array length should be 12 document.append("_id", new ObjectId(new Date())); //ObjectId constructor also takes Date as argument
但是,如果我们试图通过传递一些参数来创建ObjectId实例,例如document.append(" _ id",new ObjectId(" 1234"));
,它将抛出以下异常。
Exception in thread "main" java.lang.IllegalArgumentException: invalid hexadecimal representation of an ObjectId: [1234] at org.bson.types.ObjectId.parseHexString(ObjectId.java:549) at org.bson.types.ObjectId.<init>(ObjectId.java:239) at com.theitroad.mongodb.main.MongoDBInsertExample.main(MongoDBInsertExample.java:24)
这是因为在为ObjectId传递参数时已经进行了一些验证,因此传递的String应该是十六进制字符串。
您可以查看其源代码以获取更多详细信息。
如果您尝试传递ObjectId,例如document.append(" _ id",new ObjectId(" 1234" .getBytes())
;,则会引发以下异常。
Exception in thread "main" java.lang.IllegalArgumentException: state should be: buffer.remaining() >=12 at org.bson.assertions.Assertions.isTrueArgument(Assertions.java:62) at org.bson.types.ObjectId.<init>(ObjectId.java:272) at org.bson.types.ObjectId.<init>(ObjectId.java:249) at com.theitroad.mongodb.main.MongoDBInsertExample.main(MongoDBInsertExample.java:33)
原因是字节数组的最小大小应为12。
- MongoDB插入Map Java程序
如果您查看上面的"文档"示例,就会发现它与Map非常相似。
我们可以轻松地将Map插入为文档,示例代码段如下所示。
Map<String,Object> dataMap = new HashMap<String,Object>(); dataMap.put("name", "hyman"); dataMap.put("country", "USA"); dataMap.put("_id",new ObjectId("123459789012".getBytes())); Document document = new Document(dataMap); col.insertOne(document);
- MongoDB插入JSON文档
有时我们会得到JSON响应,主要是在调用Web服务时。
因此,MongoDB提供了一种简单的方法来在MongoDB集合中插入JSON文档,如下面的示例所示。
String json = "{ 'name' : 'hyman', 'country' : 'USA' }"; Document document = Document.parse(json); col.insertOne(document);
- 插入多个文件
我们也可以使用Mongo Java驱动程序插入多个文档,下面显示一个简单的示例。
package com.theitroad.mongodb.main; import java.util.ArrayList; import java.util.List; import org.bson.Document; import com.mongodb.MongoClient; import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoDatabase; public class MongoDBInsertMultipleExample { public static void main(String[] args) { MongoClient mongo = new MongoClient("localhost", 27017); MongoDatabase db = mongo.getDatabase("theitroad"); MongoCollection<Document> col = db.getCollection("Persons"); List<Document> docs = new ArrayList<>(); docs.add(new Document("name", "hyman")); docs.add(new Document().append("name", "David")); col.insertMany(docs); for(Document doc : docs) { System.out.println("Name="+doc.getString("name")+", ID="+doc.getObjectId("_id").toString()); } mongo.close(); } }
产生的输出将如下所示。
Name=hyman, ID=59a404c9c5130d39760a01a2 Name=David, ID=59a404c9c5130d39760a01a3