Mongodb 主键:使用 ObjectId() 设置 _id 字段的示例

⚡ 智能摘要

MongoDB 主键是用于唯一标识集合中每个文档的 _id 字段。默认情况下,它包含一个自动生成的 ObjectId,但您也可以在插入文档时为 _id 字段分配自定义值。

  • ???? 主要职责: _id 字段是主键,用于唯一标识文档中的每个文档。 MongoDB 采集。
  • 🆔 默认对象 ID: 如果省略 _id, MongoDB 自动向文档添加唯一的 12 字节 ObjectId 值。
  • ⏱️ 按时间顺序排列: ObjectId 以 4 字节时间戳开头,因此 ID 大致可以按创建时间排序。
  • ✍️ 自定义密钥: 插入文档时,您可以提供自己的 _id 值,例如数字或字符串。
  • 🔒 一成不变的: 一旦设置,_id 值无法更改;必须删除并重新插入才能更改它。

什么是主键 MongoDB?

In MongoDB,_id 字段作为集合的主键,以便每个文档都可以在集合中唯一标识。_id 字段包含唯一的 ObjectID 值。

默认情况下,在集合中插入文档时,如果没有添加字段名称中包含 _id 的字段名称,则 MongoDB 将自动添加一个 Object id 字段,如下所示

主键 MongoDB

当查询集合中的文档时,您可以看到集合中每个文档的 ObjectId。

如果你想确保 MongoDB 在创建集合时不会创建 _id 字段,如果您想指定自己的 id 作为集合的 _id,那么您需要在创建集合时明确定义这一点。

当明确创建 id 字段时,需要在其名称中使用 _id 来创建。

让我们看一个例子来了解如何实现这一点。

db.Employee.insert({_id:10, "EmployeeName" : "Smith"})

Code 说明:

  1. 我们假设正在创建集合中的第一个文档,因此在创建集合时的上述语句中,我们明确定义字段 _id 并为其定义一个值。

如果命令执行成功,现在使用 find 命令显示集合中的文档,将显示以下输出

输出:

主键 MongoDB

输出清楚地表明,我们在创建集合时定义的 _id 字段现在用作集合的主键。

什么是 ObjectId? MongoDB?

ObjectId 是默认值类型, MongoDB 分配给 _id 主键。这是一个 12 字节的标识符,旨在跨服务器和集合全局唯一,因此两个文档几乎永远不会获得相同的值。因为客户端驱动程序无需向服务器请求即可生成 ObjectId, MongoDB 无需中央计数器即可快速插入文档并扩展到多台机器。

每个 ObjectId 都以紧凑的二进制形式存储,但显示为 24 个字符的十六进制字符串,例如 ObjectId(“507f1f77bcf86cd799439011”)。前几个字节基于当前时间,这意味着随着文档的创建,这些值会稳步递增。这使得 ObjectId 不仅唯一,而且可以大致按插入顺序排序,当您想要优先显示最新或最旧的记录时,这是一个非常有用的特性。

一个结构 MongoDB 对象标识

A MongoDB ObjectId 的长度正好是 12 个字节,每个部分都有特定的含义。理解这种结构有助于解释为什么 ObjectId 是唯一的并且按时间顺序排列:

  • 4字节时间戳: 自 Unix 纪元以来的秒数,记录对象 ID 的创建时间。这使得 ID 可以按时间排序。
  • 5字节随机值: 每个进程生成一次的值,结合了机器和进程标识,因此不同的客户端会生成不同的 ID。
  • 3字节递增计数器: 一个计数器,从随机值开始,并随着同一秒内每个新的 ObjectId 的增加而递增,从而防止快速插入期间发生冲突。

这三个部分共同确保每个 ObjectId 都是唯一的,即使多个文档同时插入到不同的服务器上也是如此。您可以随时通过调用 ObjectId 的 getTimestamp() 方法读取其嵌入的创建时间。

使用 ObjectId 作为主键的优势

使用默认的 ObjectId 作为 _id 主键有几个实际的好处,这也是为什么大多数情况下都这样做的原因。 MongoDB 收藏品依赖于它:

  • 自动生成: 您无需自行创建或管理键值,从而降低了出现重复键的几率。
  • 全球独特性: ObjectId 在各个服务器上保持唯一性,因此它们在分布式和分片部署中效果很好。
  • 内置时间戳: 内置的创建时间允许您按文档的创建时间进行排序或筛选,而无需额外的日期字段。
  • 高性能: 客户端生成避免了与服务器的往返通信,保持ping 快速插入。

虽然 ObjectId 适用于大多数应用场景,但当使用自然的业务键能简化查询时,您仍然可以选择自定义 _id,例如电子邮件地址或产品代码。正确的选择取决于您计划如何查找和关联数据。

常见问题

不。文档创建后,_id 字段是不可变的。要更改它,必须删除现有文档,然后插入一个具有所需 _id 值的新文档。

_id 字段接受大多数 BSON 类型,包括 ObjectId、整数、字符串,甚至嵌入式文档。唯一的规则是该值在集合中必须是唯一的,并且不能是数组。

是的。 MongoDB 系统会自动为每个集合的 _id 字段创建一个唯一索引。此索引无法删除,并且可以极大地加快通过主键进行查找的速度。

AI可以解释ObjectId的时间戳,并生成代码来解释示例。trac使用 getTimestamp() 获取创建时间,并将 ObjectIds 转换为字符串,帮助ping 开发人员可以更快地调试和理解文档标识符。

是的。AI 可以根据您的查询模式、唯一性需求和分片计划,建议是保留默认的 ObjectId 还是使用自定义的 _id,例如电子邮件或 UUID。

总结一下这篇文章: