Skip to content

MongoDB ObjectId

在 MongoDB 中,ObjectId 是一种特殊类型的字段,用于唯一标识集合中的文档。ObjectId 是 MongoDB 自动生成的,并且具有一定的结构和特性。

基本概念

ObjectId 的结构

ObjectId 是一个 12 字节的 BSON 类型字段,由以下几部分组成:

  1. 时间戳:前 4 字节表示 ObjectId 的创建时间。
  2. 机器标识符:接下来的 3 字节表示机器的标识符。
  3. 进程标识符:接下来的 2 字节表示进程的标识符。
  4. 计数器:最后 3 字节表示计数器,用于确保 ObjectId 的唯一性。

ObjectId 的特性

  1. 唯一性:每个 ObjectId 都是唯一的。
  2. 单调性:ObjectId 是单调递增的。
  3. 紧凑性:ObjectId 的大小只有 12 字节,比 UUID 更紧凑。
  4. 可排序性:ObjectId 可以按照时间戳进行排序。

生成 ObjectId

MongoDB 自动生成

在 MongoDB 中,当我们插入文档时,如果没有指定 _id 字段,MongoDB 会自动生成一个 ObjectId。

javascript
// 插入文档时,MongoDB 会自动生成 _id 字段
db.users.insertOne({
  name: "John",
  age: 30,
  email: "john@example.com",
  status: "active"
})

手动生成

我们也可以手动生成 ObjectId。

javascript
// 手动生成 ObjectId
const ObjectId = require("mongodb").ObjectId
const id = new ObjectId()

console.log(id)

查询 ObjectId

查询单个文档

javascript
// 查询单个文档
db.users.findOne({ _id: ObjectId("5e8f8f8f8f8f8f8f8f8f8f8f") })

查询多个文档

javascript
// 查询多个文档
db.users.find({
  _id: {
    $in: [
      ObjectId("5e8f8f8f8f8f8f8f8f8f8f8f"),
      ObjectId("5e8f8f8f8f8f8f8f8f8f8f90"),
      ObjectId("5e8f8f8f8f8f8f8f8f8f8f91")
    ]
  }
})

ObjectId 的操作

获取创建时间

我们可以通过 ObjectId 获取文档的创建时间。

javascript
// 获取文档的创建时间
const id = ObjectId("5e8f8f8f8f8f8f8f8f8f8f8f")
const createdAt = id.getTimestamp()

console.log(createdAt)

转换为字符串

我们可以将 ObjectId 转换为字符串。

javascript
// 将 ObjectId 转换为字符串
const id = ObjectId("5e8f8f8f8f8f8f8f8f8f8f8f")
const idStr = id.toString()

console.log(idStr)

比较 ObjectId

我们可以比较两个 ObjectId 的大小。

javascript
// 比较两个 ObjectId 的大小
const id1 = ObjectId("5e8f8f8f8f8f8f8f8f8f8f8f")
const id2 = ObjectId("5e8f8f8f8f8f8f8f8f8f8f90")

console.log(id1 < id2) // 输出 true
console.log(id1 > id2) // 输出 false

ObjectId 的最佳实践

使用 MongoDB 自动生成的 ObjectId

在大多数情况下,我们应该使用 MongoDB 自动生成的 ObjectId,因为它具有唯一性、单调性和紧凑性等特性。

不要修改 ObjectId

我们不应该修改 ObjectId,因为它是文档的唯一标识符。如果我们修改了 ObjectId,可能会导致文档的一致性问题。

避免使用 ObjectId 作为业务主键

虽然 ObjectId 可以作为文档的唯一标识符,但我们不应该将其作为业务主键,因为它的结构和特性不适合作为业务主键。

总结

在 MongoDB 中,ObjectId 是一种特殊类型的字段,用于唯一标识集合中的文档。ObjectId 由时间戳、机器标识符、进程标识符和计数器组成,具有唯一性、单调性和紧凑性等特性。在大多数情况下,我们应该使用 MongoDB 自动生成的 ObjectId,因为它具有良好的特性。同时,我们也应该避免修改 ObjectId 和将其作为业务主键。