Skip to content

MongoDB 数据库引用

在 MongoDB 中,我们可以使用数据库引用来表示文档之间的关系。数据库引用允许我们在一个文档中引用另一个文档,从而实现数据的关联查询。

基本概念

数据库引用的类型

  1. DBRef:MongoDB 官方推荐的数据库引用类型。
  2. 手动引用:我们自己定义的数据库引用类型。

DBRef 的结构

DBRef 是一个包含以下字段的文档:

  1. $ref:要引用的集合名称。
  2. $id:要引用的文档的 _id 字段。
  3. $db(可选):要引用的数据库名称。

创建 DBRef

javascript
// 创建 DBRef
const dbRef = {
  $ref: "orders",
  $id: ObjectId("5e8f8f8f8f8f8f8f8f8f8f90"),
  $db: "mydatabase"
}

// 将 DBRef 嵌入到用户文档中
db.users.updateOne(
  { _id: ObjectId("5e8f8f8f8f8f8f8f8f8f8f8f") },
  { $set: { orderRef: dbRef } }
)

查询 DBRef 引用的文档

javascript
// 查询用户文档
const user = db.users.findOne({ _id: ObjectId("5e8f8f8f8f8f8f8f8f8f8f8f") })

// 解析 DBRef
const order = db[user.orderRef.$ref].findOne({ _id: user.orderRef.$id })

console.log(order)

使用 $lookup 解析 DBRef

在 MongoDB 中,我们可以使用 $lookup 操作符来解析 DBRef。

javascript
// 解析 DBRef
db.users.aggregate([
  {
    $lookup: {
      from: "orders",
      localField: "orderRef.$id",
      foreignField: "_id",
      as: "order"
    }
  }
])

手动引用

除了 DBRef,我们还可以使用手动引用来表示文档之间的关系。手动引用是指在文档中直接存储另一个文档的 _id 字段。

javascript
// 用户文档
{
  _id: ObjectId("5e8f8f8f8f8f8f8f8f8f8f8f"),
  name: "John",
  email: "john@example.com",
  orderId: ObjectId("5e8f8f8f8f8f8f8f8f8f8f90")
}

// 订单文档
{
  _id: ObjectId("5e8f8f8f8f8f8f8f8f8f8f90"),
  product: "iPhone X",
  price: 999,
  quantity: 1
}

查询手动引用的文档

javascript
// 查询用户文档
const user = db.users.findOne({ _id: ObjectId("5e8f8f8f8f8f8f8f8f8f8f8f") })

// 查询订单文档
const order = db.orders.findOne({ _id: user.orderId })

console.log(order)

使用 $lookup 解析手动引用

javascript
// 解析手动引用
db.users.aggregate([
  {
    $lookup: {
      from: "orders",
      localField: "orderId",
      foreignField: "_id",
      as: "order"
    }
  }
])

DBRef 与手动引用的比较

DBRef 的优点

  1. 标准化:DBRef 是 MongoDB 官方推荐的数据库引用类型。
  2. 明确性:DBRef 明确地指出了要引用的集合和数据库。
  3. 可读性:DBRef 的结构更清晰,更易于理解。

DBRef 的缺点

  1. 性能:解析 DBRef 需要额外的查询操作,会降低查询性能。
  2. 复杂性:DBRef 的结构更复杂,需要更多的代码来解析。

手动引用的优点

  1. 性能:手动引用的解析过程更简单,查询性能更高。
  2. 简单性:手动引用的结构更简单,需要更少的代码来解析。

手动引用的缺点

  1. 不标准化:手动引用没有统一的格式,可能会导致代码的不一致性。
  2. 不明确性:手动引用没有明确地指出要引用的集合和数据库,可能会导致混淆。

总结

在 MongoDB 中,我们可以使用数据库引用来表示文档之间的关系。数据库引用允许我们在一个文档中引用另一个文档,从而实现数据的关联查询。MongoDB 提供了两种数据库引用类型:DBRef 和手动引用。DBRef 是官方推荐的数据库引用类型,它的结构更清晰,更易于理解,但查询性能较低。手动引用的结构更简单,查询性能更高,但没有统一的格式,可能会导致代码的不一致性。在选择数据库引用类型时,我们应该根据实际需求来决定。