Skip to content

MongoDB - 插入文档

本章介绍如何使用现代推荐的方法将文档插入到 MongoDB 集合中。我们将重点介绍 insertOne() 和 insertMany() 方法,它们为数据库操作提供了清晰明确的意图。

现代插入方法:insertOne() 和 insertMany()

Section titled “现代插入方法:insertOne() 和 insertMany()”

在现代 MongoDB 版本中,添加新文档的主要方法是用于插入单个文档的 insertOne() 和用于在一次操作中插入多个文档的 insertMany()。与旧版 insert() 方法相比,这些方法因其明确的性质和更清晰的返回值而更受青睐。

**废弃通知:** 旧版 `db.collection.insert()` 和 `db.collection.save()` 方法已被废弃(deprecated)。尽管它们在某些版本中可能仍可用于向后兼容,但在新应用中应始终使用 `insertOne()`、`insertMany()` 或 `replaceOne()`/`updateOne()`,以确保代码清晰和未来兼容性。

使用 insertOne() 方法将单个文档插入到集合(collection)中。如果集合当前不存在,MongoDB 会在第一次插入时创建它。

db.collectionName.insertOne(
<document>,
{ writeConcern: <document> }
)

writeConcern 选项指定了从 MongoDB 请求写入操作确认的级别。这是一个高级主题,在大多数用例中,默认值就已足够。

让我们向 users 集合中插入一个文档。如果我们不提供 _id 字段,MongoDB 会自动为其生成一个唯一的 ObjectId。

> db.users.insertOne({
... name: "Alice Johnson",
... email: "alice.j@example.com",
... roles: ["user", "editor"],
... signupDate: new Date(),
... profile: {
... age: 28,
... city: "New York"
... }
... })
{
acknowledged: true,
insertedId: ObjectId("64a5f1e1a2b3c4d5e6f7a8b9")
}

_id 字段是集合的主键,并且对于每个文档都必须是唯一的。如果您不指定 _id,MongoDB 会自动生成一个唯一的 12 字节 ObjectId。其结构为:

_id: ObjectId(
[4-byte timestamp],
[5-byte random value],
[3-byte incrementing counter]
)

要一次性插入多个文档,请使用 insertMany() 方法。这比在循环中多次调用 insertOne() 效率更高,因为它只需要一次数据库往返(round trip)。

db.collectionName.insertMany(
[ <document1>, <document2>, ... ],
{ writeConcern: <document>, ordered: <boolean> }
)

ordered 选项(默认为 true)指定 MongoDB 是执行有序插入还是无序插入。在有序插入中,如果发生错误,MongoDB 会停止处理剩余的文档。在无序插入中,它会尝试插入所有文档,无论是否发生错误。

> db.products.insertMany([
... {
... name: "Laptop Pro 15-inch",
... category: "Electronics",
... price: 1299.99,
... tags: ["computer", "pro", "work"],
... stock: 50
... },
... {
... name: "Wireless Mouse",
... category: "Accessories",
... price: 49.99,
... tags: ["input", "ergonomic"],
... stock: 200
... },
... {
... _id: "custom_monitor_id_123", // Providing a custom _id
... name: "4K UHD Monitor",
... category: "Electronics",
... price: 399.00,
... tags: ["display", "4k"],
... stock: 75
... }
... ])
{
acknowledged: true,
insertedIds: [
ObjectId("64a5f2e2a2b3c4d5e6f7a8ba"),
ObjectId("64a5f2e2a2b3c4d5e6f7a8bb"),
'custom_monitor_id_123'
]
}
  • 使用批量操作: 对于插入多个文档,始终优先使用 insertMany() 而不是多次调用 insertOne(),以减少网络开销。
  • 错误处理: 在应用程序中使用 MongoDB 驱动程序时(例如 Node.js、Python),请将插入操作封装在 try-catch 块中,以处理潜在错误,例如重复键(duplicate keys)或连接问题。
  • 模式验证(Schema Validation): 对于生产应用程序,请考虑使用 MongoDB 的模式验证(Schema Validation)功能来强制文档保持一致的结构,从而防止意外插入格式错误的数据。
  • 重复键错误 (E11000): 当您尝试插入一个 _id 已存在于集合中的文档时,会发生此错误。请确保您的 _id 值是唯一的。
  • 写入确认失败(Write Concern Failed): 如果写入操作无法由 write concern 中指定的节点数量确认,则在副本集(replica sets)中可能会发生此错误。这通常表明存在复制或网络问题。
  • BSON 大小超出限制: 单个 MongoDB 文档不能超过 16 MB。如果需要存储更大的数据,请考虑使用 GridFS 或将数据拆分为多个文档。