如果你自己做(即没有Mongoose这样的对象建模库),你的第二个选择是最有利的设计。根据
docs
手册参考:
手动参考是将一个文档的_id字段包含在另一个文档中的做法。然后,应用程序可以根据需要发出第二个查询来解析引用的字段。
例如:
db.products.findOne();
{
_id: ObjectId("64f8cd127f6c107e984014fc"),
name: 'Hat',
}
db.users.findOne({ _id : ObjectId("64f8cbb87f6c107e984014f5")});
{
_id: ObjectId("64f8cbb87f6c107e984014f5"),
first_name: 'Bob',
last_name: 'Smith',
address: '123 Tree Lane'
}
db.carts.findOne({ user_id : ObjectId("64f8cbb87f6c107e984014f5") });
{
_id: ObjectId("64f8cd507f6c107e984014ff"),
product_id: ObjectId("64f8cd127f6c107e984014fc"),
user_id: ObjectId("64f8cbb87f6c107e984014f5")
}
然后,您可以执行
$lookup
以联接类似于SQL中的左联接的文档。
db.carts.aggregate([
{ $match: { user_id: ObjectId("64f8cbb87f6c107e984014f5") } },
{
$lookup:
{
from: "users",
localField: "user_id",
foreignField: "_id",
as: "user_details"
}
}
])
[
{
_id: ObjectId("64f8cd507f6c107e984014ff"),
product_id: ObjectId("64f8cd127f6c107e984014fc"),
user_id: ObjectId("64f8cbb87f6c107e984014f5"),
user_details: [
{
_id: ObjectId("64f8cbb87f6c107e984014f5"),
first_name: 'Bob',
last_name: 'Smith',
address: '123 Tree Lane'
}
]
}
]
这使得管理数据基于
_id
易于管理。
然而,这非常像关系数据库的设计,MongoDB是NoSQL,因此它是专门为利用在彼此中存储文档而设计的。我建议你读一下
embedded documents
并尽可能使用它们。
你的
cart
可以存储的数组
product_id
就像这样:
db.carts.findOne({ user_id : ObjectId("64f8cbb87f6c107e984014f5") });
{
_id: ObjectId("64f8cd507f6c107e984014ff"),
products:[
{ product_id: ObjectId("64f8cd127f6c107e984014fc") },
{ product_id: ObjectId("64f8d35c7f6c107e98401512") }
],
user_id: ObjectId("64f8cbb87f6c107e984014f5")
}
然后,如果你想在中加入产品详细信息,你可以这样做:
db.carts.aggregate([
{ $match: { user_id: ObjectId("64f8cbb87f6c107e984014f5") } },
{
$lookup:
{
from: "products",
localField: "products.product_id",
foreignField: "_id",
as: "product_details"
}
}
])
[
{
_id: ObjectId("64f8cd507f6c107e984014ff"),
user_id: ObjectId("64f8cbb87f6c107e984014f5"),
products: [
{ product_id: ObjectId("64f8cd127f6c107e984014fc") },
{ product_id: ObjectId("64f8d35c7f6c107e98401512") }
],
product_details: [
{ _id: ObjectId("64f8cd127f6c107e984014fc"), name: 'Hat' },
{ _id: ObjectId("64f8d35c7f6c107e98401512"), name: 'Shoe' }
]
}
]