我正在尝试在 MongoDB Atlas 中为电子商务应用程序实现购物车集合,但不确定引用用户购物车中位于单独集合中的产品的正确方法。
我可以使用产品的文档 ID 作为购物车文档中的密钥吗?即
cart = {
productID1: productQty1,
productID2: productQty2,
...
}
或者我需要做这样的事情:
cart = [
{
productID: productID1,
qty: productQty1,
},
{
productID: productID2,
qty pro
},
...
]
其中productID1是产品集合中对应产品文档的_id?
由于 _id 是 ObjectID 类型,我不确定是否可以/应该将其用作字符串类型的键,或者使用 docID 作为键而不是值是否存在潜在问题。
如果您自己这样做(即没有诸如 Mongoose 之类的对象建模库),您的第二个选择是最有利的设计。根据手册参考的docs:
手动引用是将一个文档的 _id 字段包含在另一个文档中的做法。然后,应用程序可以发出第二个查询来根据需要解析引用的字段。
例如:
db.products.findOne(); // Find first item in products collection
// Returns
{
_id: ObjectId("64f8cd127f6c107e984014fc"),
name: 'Hat',
}
db.users.findOne({ _id : ObjectId("64f8cbb87f6c107e984014f5")}); // Find a user by their _id
// Returns
{
_id: ObjectId("64f8cbb87f6c107e984014f5"),
first_name: 'Bob',
last_name: 'Smith',
address: '123 Tree Lane'
}
db.carts.findOne({ user_id : ObjectId("64f8cbb87f6c107e984014f5") }); // Find a cart by user_id
// Returns
{
_id: ObjectId("64e929c430d0784f63be7a7f"),
user_id: ObjectId("64f8cbb87f6c107e984014f5"), // Bob
product_id: ObjectId("64f8cd127f6c107e984014fc") // Hat
}
然后您可以执行 $lookup 来连接文档,类似于 SQL 中的左连接。
db.carts.aggregate([
{ $match: { user_id: ObjectId("64f8cbb87f6c107e984014f5") } }, // Find Bob's cart
{
$lookup: // Now lookup Bob's details and add them as "user_details"
{
from: "users",
localField: "user_id",
foreignField: "_id",
as: "user_details"
}
}
])
// Returns
[
{
_id: ObjectId("64f8cd507f6c107e984014ff"),
product_id: ObjectId("64f8cbb87f6c107e984014f5"),
user_id: ObjectId("64f8cbb87f6c107e984014f5"),
user_details: [
{
_id: ObjectId("64f8cbb87f6c107e984014f5"),
first_name: 'Bob',
last_name: 'Smith',
address: '123 Tree Lane'
}
]
}
]
这使得基于
_id
的数据管理变得简单。
但是,这非常类似于 SQL 设计,并且 MongoDB 专为利用彼此存储文档而定制。我建议您阅读嵌入式文档并尽可能使用它们。