将喜欢/收藏/评论/关注保存在MongoDB中的最佳方法是什么?

时间:2019-04-15 10:53:37

标签: mongodb

我正在尝试从摄影网站学习MongoDB。在此页面上,每个图像都分配到一个位置。每个位置可以包含来自不同用户的许多图像。

目前,我有三个收藏夹。用户,景点(针对位置)和Spotimage。

我现在要做什么:
 -用户应该能够喜欢图片。
 -用户应该可以将地点添加到自己的收藏夹中(最后也可以添加点赞,但该收藏夹应仅显示在用户的个人资料中)。
 -用户应该能够对景点和图片发表评论。
 -用户应该能够关注其他用户以及各个地点。

最有效的点赞/收藏/评论/关注在哪里保存?
在用户想要的文档上,或者在用户自己的文档上。

我认为,两者都将起作用(为什么不起作用),但是最有效的是什么?还是有一种完全不同的方法来更好地做到这一点?

我还阅读了有关喜欢/评论/等的自己的收藏。但是在其他页面上,您可以看到这不是最佳方法。我已经多次搜索过这个问题,您总是会得到不同的建议。因此,很高兴知道一个或另一个变体为何更快/更好。

当前,我在集合spotimages中有一个包含对象的数组。每个对象都包含用户ID和日期。此外,我单独保存了“点赞”的数量(也保存在Spotimages集合中),每次更改时增加或减少1。


if(alreadyLiked == true){

    const imageLikedBy = { "userId": userId }
    const interaction = await SpotImage.updateOne( { _id: interactionInput.id }, { $pull: { likedBy: imageLikedBy }, $inc: { likes: -1 } } )

    return interaction

}else{

    const imageLikedBy = { "userId": userId, "datetime": new Date() }
    const interaction = await SpotImage.updateOne( { _id: interactionInput.id }, { $push: { likedBy: imageLikedBy }, $inc: { likes: 1 } } )

    return interaction

}
{
    "_id":"5c89241f40e5b33da6a979ea",
    "ownedBy":"5c5d7339f49e124ce6ceb63f",
    [...]
    "likedBy":[{
        "userId":"5cacfa79bcd8614feb52e085",
    "datetime":"2019-04-10T20:43:06.369Z"
    }],
    "likes":1
}

我按照相同的逻辑保存收藏夹。但是在景点集合中。 我的项目中目前没有评论与关注,但将来会存在,因为我有相同的问题...

每个收藏集中的一个样本文档:

用户:

{
    "_id":"5c5d7339f49e124ce6ceb63f",
    "firstname":"...",
    "surname":"...",
    "username":"...",
    "email":"mail@....com",
    "password":"..",
    "img_name":"...",
    "createdAt":"2019-02-08T12:16:57.658Z",
    "updatedAt":"2019-04-13T16:19:52.351Z",
    "__v":0,
    "description":"...",
    "access":"9",
    "social":{
        "website":"https://....com",
        "facebook":"https://facebook.com/...",
        "instagram":"https://www.instagram.com/...",
        "youtube":"https://youtube.com/channel/..."
    }
}

景点:

{
    "_id":"5c925c32db973e4224dae9eb",
    "location":{
        "coordinates":[10.749331,47.579609],
        "type":"Point"
    },
    "hashtags":[...],
    "modifiedBy":[{
        "userId":"5c9257eddb973e4224dae9ea",
        "typ":"created",
        "datetime":"2019-03-20T15:28:50.781Z"
    }],
    "name":"St. Coloman",
    "description":"A small but very special and unique church in front of impressive mountains.",
    "photography_tips":"Best spot for taking a picture is In front of the church about 100 meters away.",
    "access_information":"The village is named \"Schwangau\". You will find the church on your way to the castle.",
    "address":"St. Coloman, 95, Colomanstraße, Horn, Schwangau, Landkreis Ostallgäu, Swabia, Bavaria, 87645, Germany",
    "createdAt":"2019-03-20T15:28:50.782Z",
    "updatedAt":"2019-04-13T20:30:19.308Z",
    "__v":0,
    "favoriteBy":[{
        "userId":"5c5d7339f49e124ce6ceb63f",
        "datetime":"2019-04-13T20:30:19.308Z"
    }],
    "favorites":1
}

spotimages:

{
    "_id":"5c925c32db973e4224dae9ec",
    "hashtags":[...],
    "file_name":"f4048202b540cd0d2b810c7a1242a684",
    "name":"LRM_EXPORT_192313666969612_20190119_202136264.jpeg",
    "spotId":"5c925c32db973e4224dae9eb",
    "ownedBy":"5c9257eddb973e4224dae9ea",
    "createdAt":"2019-03-20T15:28:50.784Z",
    "updatedAt":"2019-04-09T10:17:34.046Z",
    "__v":0,
    "likedBy":[{
        "userId":"5c5d7339f49e124ce6ceb63f",
        "datetime":"2019-04-09T10:17:34.045Z"
    }],
    "likes":1
}

1 个答案:

答案 0 :(得分:0)

问题到了关键点,即这些实体中的哪一个(用户,斑点和斑点图像)是您的主要实体。 MongoDB中使用了两种类型的数据模型-

  1. 嵌入式/非规范化数据模型-通常,在以下情况下使用嵌入式数据模型:
    • 您在实体之间具有“包含”关系。
    • 您在实体之间具有一对多关系。在这些关系中,“许多”或子级文档始终与“一个”或父级文档一起出现或在上下文中查看。
  2. 归一化数据模型-您的单独集合结构位于该数据模型下。这用于:
    • 嵌入时会导致数据重复,但无法提供足够的读取性能优势,胜过重复所带来的影响。
    • 代表更复杂的多对多关系。

供参考,请参考此链接: https://docs.mongodb.com/manual/core/data-model-design/


示例:让我们考虑一下,您将斑点图像作为主要实体。但是,在显示该图像时,您还需要获取喜欢/添加注释的用户的名称,最好将图像和用户存储在嵌入式文档结构中。

但是,如果嵌入导致数据重复,我建议您继续遵循您遵循的规范化结构。