适用于用户收藏夹的Mongo DB Design(优点和缺点)

时间:2019-04-27 08:32:15

标签: mongodb

我需要拥有2个API

1)检索衣服列表(同时检查哪些物品是用户的最爱,并用心形标记)

2)检索用户最喜欢的衣服列表

enter image description here

我应该如何存储用户收藏夹?

到目前为止我发现的内容:

将所有用户的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引用数组。

对此有什么补救办法?

1 个答案:

答案 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();