我需要拥有2个API
1)检索衣服列表(同时检查哪些物品是用户的最爱,并用心形标记)
2)检索用户最喜欢的衣服列表
我应该如何存储用户收藏夹?
到目前为止我发现的内容:
将所有用户的ID嵌入“服装”文档中的每个服装中。并在“用户”文档中保留用户最喜欢的数组。为了找出用户最喜欢的衣服,我们将利用ID字段在“衣服”和“用户”文档之间进行匹配。
服装收藏:
{
"id" : "clothesID01",
"images": [
{"imgUrl": "https://s3-ap-1.amazonaws.com/rental/img1.png"},
{"imgUrl": "https://s3-ap-1.amazonaws.com/rental/img2.png"},
{"imgUrl": "https://s3-ap-1.amazonaws.com/rental/img3.png"}
],
"brand" : "Halo",
"title" : "Cheryl Dress",
"retailPrice" : {
"currency": "USD",
"amount": 447
},
"description":"Halo pieces are xxxx",
"favorites" : [
{"userId" : "user01"},
{"userId" : "user02"}
],
"isPremium" : true,
"publishedDate" : "2019-04-04T06:12:46.839+00:00"
...
}
用户集合:
{
"id": "user01",
"phoneNumber": "+123456789",
"favourites":[
{"clothesId" : "clothesID01"},
{"clothesId" : "clothesID04"}
]
...
}
基于规则{3中的Rules of thumb for mongoDB Design
如果“许多”方面有数千个文档, 不要使用ObjectID引用数组
“衣服”文档的收藏夹可能由大约10万名用户(交叉手指)组成,这可能不适合使用ObjectID引用数组。
对此有什么补救办法?
答案 0 :(得分:1)
首先,您根本不需要将喜欢的数据存储在衣服集合中。除了您发现的问题之外,每当两个用户同时更新喜欢的同一个服装时,您还将处于竞赛状态。
相反,仅将用户的收藏夹存储在User集合中,然后,如果ClothesID与用户的收藏夹列表匹配,则在渲染阶段突出显示心形。
第二,使用字典哈希图进行更具表现力的查找,而不是需要搜索每个项目的列表。
{
"id": "user01",
"phoneNumber": "+123456789",
"favourites": {
"clothesID01": true,
"clothesID04": true
}
}
当您想知道衣服ID是否为收藏夹时,可以检查
if (user.favourites[clothesID] === true)
这不需要遍历数组中的每个项目,而是只检查内存中的一个特定位置。
因此您将使用直接查询:
1)检索衣服列表(同时检查哪些物品是用户的最爱,并用心形标记)
const user = await db.User.findOne(ObjectId(userId));
const clothes = await db.Clothes.find(query).toArray();
for(let article of clothes) {
if(user.favourites[article.clotheId]) {
// display full heart
}
}
2)检索用户最喜欢的衣服列表
const user = await db.User.findOne(ObjectId(userId), {favourites:true});
const favouriteIds = Object.keys(user.favourites);
const favourites = await db.Collection.find({_id: {$in: favouriteIds}}).toArray();