MongoDB ObjectId 详解
                           
天天向上
发布: 2025-03-09 09:34:56

原创
472 人浏览过

1. 什么是 ObjectId?

ObjectId 是 MongoDB 文档的默认唯一标识符(_id)。它是一个 12 字节 的 BSON 类型值,MongoDB 自动为每个文档生成一个 ObjectId,但用户也可以手动指定。


2. ObjectId 的结构

MongoDB 的 ObjectId12 字节 组成,结构如下:

字节数内容说明
4 字节时间戳记录 ObjectId 生成的秒级时间戳(Unix 时间)
5 字节随机值机器唯一标识,防止不同机器生成相同 ObjectId
3 字节计数器递增的计数器,确保同一秒内的多个 ObjectId 唯一
  • 示例 ObjectId
  65f3a13f4c7d6b58d0c8a7e2

拆解:

  • 65f3a13f(时间戳)
  • 4c7d6b58d0(随机值)
  • c8a7e2(计数器)

3. 如何生成 ObjectId

(1) MongoDB 自动生成

如果不指定 _id,MongoDB 在插入文档时会自动生成 ObjectId

db.users.insertOne({ name: "Alice" })

自动生成:

{
  "_id": ObjectId("65f3a13f4c7d6b58d0c8a7e2"),
  "name": "Alice"
}

(2) 手动创建 ObjectId

可以使用 ObjectId() 方法手动创建:

db.users.insertOne({ _id: ObjectId("65f3a13f4c7d6b58d0c8a7e2"), name: "Bob" })

或者在 JavaScript 中创建:

new ObjectId()

4. ObjectId 相关操作

(1) 提取 ObjectId 生成时间

由于 ObjectId 包含时间戳,可以通过 getTimestamp() 方法获取创建时间:

var id = ObjectId("65f3a13f4c7d6b58d0c8a7e2");
id.getTimestamp()

输出:

ISODate("2024-03-09T12:34:39Z")

(2) 查询特定时间范围的文档

根据 ObjectId 的时间戳,可以查找某个时间段内的文档:

db.users.find({ _id: { $gte: ObjectId.fromDate(new Date("2024-03-01")) } })

这个查询会返回 2024-03-01 之后插入的所有文档。


5. ObjectId 的特点

唯一性:全球唯一,保证不会有重复 ID。
可排序性:因为包含时间戳,ObjectId 按时间递增
节省空间:相比 UUID(16 字节),ObjectId 只占 12 字节,更节省存储。

但也有一些 限制
可预测性:如果暴露了 ObjectId,可以推测创建时间,可能带来安全风险。
不适合外部查询:不像 UUID,ObjectId 适用于 MongoDB,但不便于与外部系统兼容。


6. ObjectId vs UUID

对比项ObjectIdUUID
字节数12 字节16 字节
唯一性全球唯一全球唯一
是否包含时间✅ 包含❌ 不包含
排序特性✅ 按时间递增❌ 无顺序
存储开销较小较大
跨数据库兼容性仅 MongoDB跨系统兼容

7. 总结

  • ObjectId 是 MongoDB 的默认主键,保证唯一性、顺序性。
  • 包含时间戳,可以查询文档的创建时间。
  • 适用于大多数场景,但如果需要跨系统兼容,建议使用 UUID。

更多详细内容可以关注其他相关文章!

发表回复 0

Your email address will not be published. Required fields are marked *