插入文档

插入操作是向 MongoDB 中添加数据的基本方法。可以使用集合的 insertOne 方法插入单个文档:

db.movies.insertOne({"title" : "Stand by Me"})

mongodb字段注释 mongodb insertmany_批量插入


insertOne 会为文档自动添加一个 “_id” 键(如果你没有提供的话),并将其保存到 MongoDB 中。

insertMany

如果要向一个集合中插入多个文档,那么可以使用 insertMany。此方法可以将一个文档数组传递到数据库。这是一种更加高效的方法,因为代码不会为插入的每个文档去请求数据库,而是会批量插入它们。
可以在 shell 中尝试以下代码:

db.movies.insertMany([{"title" : "Ghostbusters"},{"title" : "E.T."},{"title" : "Blade Runner"}]);

mongodb字段注释 mongodb insertmany_驱动程序_02


一次发送数十、数百甚至数千个文档会明显提高插入的速度。

如果要将多个文档插入单个集合中,那么 insertMany 将非常有用。但如果只是导入原始数据(例如,从数据源或 MySQL 中导入),则可以使用像 mongoimport 这样的命令行工具,而不是批量插入。另外,在将数据存入 MongoDB 之前,可以使用批量插入对其做一些小的修整(比如将日期转换为日期类型,或者添加自定义的 “_id”)。在这种情况下,insertMany 同样可以用于导入数据。

在当前版本中,MongoDB 能够接受的最大消息长度是 48MB,因此在单次批量插入中能够插入的文档是有限制的。如果尝试插入超过 48MB 的数据,则多数驱动程序会将这个批量插入请求拆分为多个 48MB 的批量插入请求。详情请查看所使用驱动程序的相关文档。

在使用 insertMany 执行批量插入时,如果中途某个文档发生了某种类型的错误,那么接下来会发生什么取决于所选择的是有序操作还是无序操作。可以指定一个选项文档作为 insertMany 的第二个参数。将选项文档中的 “ordered” 键指定为 true,可以确保文档按提供的顺序插入。指定为 false 则允许 MongoDB 重新排列插入的顺序以提高性能。如果未特别指定,则默认为有序插入。对于有序插入,插入顺序由传递给 insertMany 的数组进行定义。如果一个文档产生了插入错误,则数组中在此之后的文档均不会被插入集合中。对于无序插入,MongoDB 将尝试插入所有文档,而不管某些插入是否产生了错误。

在这个例子中,因为默认情况下为有序插入,所以只有前两个文档会被插入集合中。第三个文档将产生一个错误,因为不能插入两个具有相同 “_id” 的文档:

db.movies.insertMany([
        {"_id":0,"title":"Top Gun"},
        {"_id":1,"title":"Back to the Future"},
        {"_id":1,"title":"Gremlins"},
        {"_id":2,"title":"Aliens"}])

mongodb字段注释 mongodb insertmany_mongodb_03


如果指定为无序插入,那么第一、第二和第四个文档都会被插入集合中。唯一插入失败的是第三个文档,因为存在重复的 “_id” 错误:

db.movies.insertMany([
        {"_id" : 3, "title" : "Sixteen Candles"},
        {"_id" : 4, "title" : "The Terminator"},
        {"_id" : 4, "title" : "The Princess Bride"},
        {"_id" : 5, "title" : "Scarface"}],
        {"ordered" : false})

mongodb字段注释 mongodb insertmany_mongodb字段注释_04


如果仔细研究这些示例,你可能会注意到,除了简单的插入之外,这两个对 insertMany 调用的输出提示还有其他操作可能支持批量写入。虽然 insertMany 不支持插入以外的操作,但 MongoDB 确实有一个批量写入 API 允许在单个调用中批量处理多个不同类型的操作。

插入校验

MongoDB 会对要插入的数据进行最基本的检查:检查文档的基本结构,如果不存在 “_id” 字段,则自动添加一个。其中一项最基本的结构检查就是文档大小:所有文档都必须小于 16MB。这是一个人为设定的限制(将来可能会提高),主要是为了防止不良的模式设计并确保性能上的一致。要查看doc 文档的二进制 JSON(BSON)大小(以字节为单位),可以在 shell 中执行Object.bsonsize(doc)。

为了让你对 16MB 的数据量有个概念,以《战争与和平》为例,整部著作也只有 3.14MB。

由于仅做最基本的检查,这意味着可以很容易地插入无效数据(如果你尝试这么做的话)。因此,应该只允许受信任的源(比如应用程序服务器)连接到数据库。所有主流语言的 MongoDB 驱动程序以及大部分其他语言的驱动程序,在向数据库发送任何内容之前,都会进行各种无效数据的校验(比如文档过大、包含非 UTF-8 字符串,或使用无法识别的类型)。

插入

在 MongoDB 3.0 之前,insert 是在 MongoDB 中插入文档的主要方法。在 3.0 版本的服务器端发布时,MongoDB 驱动程序引入了新的 CRUD API。从 MongoDB 3.2 开始,mongo shell 也支持这种 API,它包括 insertOne 和 insertMany 以及其他一些方法。当前 CRUD API 的目标是使所有CRUD 操作的语义在驱动程序和 shell 之间保持一致和清晰。虽然 insert 等方法仍然支持向后兼容,但今后不应该在应用程序中继续使用。应该使用 insertOne 和 insertMany 来创建文档。