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

