在关系型数据库中,外键是一种非常常见的概念,它可以用于建立表之间的关联关系。但是,在 MongoDB 这种非关系型数据库中,没有外键的概念。那么,在 MongoDB 中如何使用外键呢?
MongoDB 中的文档关系
在 MongoDB 中,文档之间的关系可以通过嵌套文档或者引用文档的方式实现。
嵌套文档
嵌套文档是指一个文档中包含另一个文档。例如,我们可以在一个订单文档中嵌套一个用户文档:
-- -------------------- ---- ------- - ------ ------------------------------------- ------- - ------ ------------------------------------- ------- ----- ------ -- -- ----------- - - ------- ------ -------- --- -- - ------- ------ -------- --- - - -展开代码
在这个例子中,订单文档中嵌套了一个用户文档,可以通过 order.user.name
来访问用户的名字。
引用文档
引用文档是指一个文档中包含了另一个文档的 _id
值。例如,我们可以在一个订单文档中引用一个用户文档:
{ "_id": ObjectId("5f2b2c2f7d2c2c4b7e0f4d0c"), "user": ObjectId("5f2b2c2f7d2c2c4b7e0f4d0b"), "products": [ { "name": "商品1", "price": 100 }, { "name": "商品2", "price": 200 } ] }
在这个例子中,订单文档中引用了一个用户文档的 _id
值,可以通过 db.users.findOne({ _id: order.user })
来访问用户文档。
如何在 MongoDB 中实现外键
虽然 MongoDB 没有外键的概念,但是我们可以通过一些方式来实现类似外键的效果。
手动维护引用关系
我们可以手动在程序中维护文档之间的引用关系。例如,在上面的例子中,我们可以在订单文档中添加一个 user_id
字段,用于存储用户文档的 _id
值。然后,在查询订单文档时,可以通过 db.users.findOne({ _id: order.user_id })
来访问用户文档。
这种方式的优点是简单易懂,缺点是需要手动维护引用关系,容易出错。
使用 $lookup 操作
MongoDB 3.2 版本以后,可以使用 $lookup 操作实现类似外键的效果。$lookup 操作可以在一个文档中查找另一个集合中的文档,并将它们合并成一个新的文档。
例如,我们可以通过以下代码查询订单文档,并将用户文档合并到订单文档中:
-- -------------------- ---- ------- --------------------- - -------- - ----- -------- ----------- ---------- ------------- ------ --- ------ - - --展开代码
这个操作会在 orders
集合中查找每个订单文档的 user_id
字段对应的 _id
值,并在 users
集合中查找对应的用户文档。然后,它会将每个订单文档和它对应的用户文档合并成一个新的文档,并将它们放在一个名为 user
的数组中。
这种方式的优点是不需要手动维护引用关系,缺点是需要使用聚合操作,效率可能较低。
示例代码
以下是一个使用 $lookup 操作实现类似外键的示例代码:
-- -------------------- ---- ------- -- -- ----- -- --------------------- - ------ ------------------------------------- ------- ----- ------ -- -- - ------ ------------------------------------- ------- ----- ------ -- - -- -- -- ------ -- ---------------------- - ------ ------------------------------------- ---------- ------------------------------------- ----------- -- ------- ------ -------- --- -- - ------- ------ -------- --- -- -- - ------ ------------------------------------- ---------- ------------------------------------- ----------- -- ------- ------ -------- --- -- - ------- ------ -------- --- -- - -- -- -------------- --------------------- - -------- - ----- -------- ----------- ---------- ------------- ------ --- ------ - - --展开代码
这个示例代码会输出以下结果:
-- -------------------- ---- ------- - - ------ ------------------------------------- ---------- ------------------------------------- ----------- - - ------- ------ -------- --- -- - ------- ------ -------- --- - -- ------- - - ------ ------------------------------------- ------- ----- ------ -- - - -- - ------ ------------------------------------- ---------- ------------------------------------- ----------- - - ------- ------ -------- --- -- - ------- ------ -------- --- - -- ------- - - ------ ------------------------------------- ------- ----- ------ -- - - - -展开代码
可以看到,每个订单文档都包含了对应的用户文档。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67d9a489a941bf7134155d14