【问题标题】:How should I structure my API or Schema based on certain requirements我应该如何根据某些要求来构建我的 API 或 Schema
【发布时间】:2021-05-12 22:41:50
【问题描述】:

我的 mongodb 数据库中有两个集合

  1. 评论
  2. 电影

comment 有一个 'movie-id' 字段,它引用评论所属的电影的 id,但 Movies 集合没有任何引用 Comment 集合的字段。

现在,如果我想通过 id 请求单个电影并显示基于该特定电影的所有 cmets,我应该进行两次 API 调用还是应该向 Movies 集合添加一个字段以引用该特定评论 id。另一种选择是根据movie_id(而不是电影)从评论中调用并按电影填充,但如果某些电影没有评论,那么这会适得其反?

如何解决?

为了更清楚这一点

这是评论数据:-

"_id": "5a9427648b0beebeb69579cc",
"name": "Andrea Le",
"email": "andrea_le@fakegmail.com",
"movie_id": "573a1390f29313caabcd418c",
"text": "Rem officiis eaque repellendus amet eos doloribus. Porro dolor voluptatum voluptates neque culpa molestias. Voluptate unde nulla temporibus ullam.",
"date": "2012-03-26T23:20:16.000Z"

还有电影数据:-

 "imdb": {
                "rating": 7.4
            },
 "_id": "573a1390f29313caabcd42e8",
 "poster": "https://m.media-amazon.com/images/M/MV5BMTU3NjE5NzYtYTYyNS00MDVmLWIwYjgtMmYwYWIxZDYyNzU2XkEyXkFqcGdeQXVyNzQzNzQxNzI@._V1_SY1000_SX677_AL_.jpg",
 "title": "The Great Train Robbery",
 "year": 1903

【问题讨论】:

    标签: node.js mongodb express mongoose


    【解决方案1】:

    如果您不必多次获取数据,那么最好只在同一个集合中包含注释。如果 cmets 不用于其他部分而仅用于电影页面,则不必对数据进行规范化。

    【讨论】:

    • 我在 mongoose 中发现了 virtual,我想这会有所帮助
    【解决方案2】:

    嗯,这里有两个不同的东西。您如何建模您的域以及如何公开它(演示文稿)。它们是非常相似的概念,开发人员通常会混淆并合并为一个单一的东西......从我的角度来看是错误的。

    首先,我认为你应该设计你的模型(我建议使用 DDD 方法),与你的表示类分开。实际上,我建议您为 API 提供输入和输出。所以我看到了这个:

    • 电影输入(api)
    • 电影输出(api)
    • 电影(对于您的业务逻辑,您保存到数据库的内容。您甚至可以在此处聚合一个防损坏层以使其与数据库无关,但这可能太多了)

    从上一个练习中,您将确定 cmets 是否应该在不同的集合中。考虑到使用 MongoDB 的众多好处(或差异)之一是您可以使用文档。这并不意味着您不能使用相关的不同集合。你可以,但 MongoDB 并不是真正为此而设计的。因此,在这种情况下,我建议您在电影集合中包含 cmets。除非您希望拥有大量的 cmets,否则您可以考虑将其取出。

    关于规范化,现在完全诚实,使用微服务、noSql 等,您应该对没有规范化的数据感到满意,并相应地设计您的系统。

    关于 API。这将取决于您的设计以及预期的使用方式。 最佳实践表明您拥有(以及我在这种情况下的建议)

    • POST /../movie - 创建。接受一个 MovieInput 并返回一个 MovieOutput
    • PUT /../movie/{id} - 更新。接受一个 MovieInput 并返回一个 MovieOutput。这应该是幂等的,实际上应该是一个替换。所以在这种情况下,你上传所有的东西,cmets 也是。如果要部分更新资源,最好使用patch
    • DELETE /.../movie/{id} - 删除包含所有 cmets 的电影
    • POST /.../movie/{id}/comment - 为该电影创建评论
    • PUT /.../movie/{id}/comment/{id} - 替换该电影的评论(幂等)
    • DELETE /.../movie/{id}/comment/{id} - 删除所有 cmets 的评论

    我省略了 GET 等。但我认为这很明显。这一切都是从我的观点和经验来看的。还有很多其他成功的方法;)

    【讨论】:

    • 但是要向电影添加评论字段,我必须检查每部电影的评论,然后如果存在我必须将其添加到电影收藏中,我应该怎么做,而不是我可以只寻找评论和单部电影并将结果都传递给响应?
    【解决方案3】:

    我对上面的答案并不满意,而且这似乎是很多工作和麻烦,这不适合聪明的开发人员。我们寻找需要较少工作和聪明代码的解决方案。

    我发现最好的方法是在 Mongoose Schema 中使用 virtuals,您可以在其中定义自己的虚拟字段(可能是对其他模型的引用),数据库看不到,但您仍然可以在响应中使用它。它也可以称为反向填充。首先了解在 mongoose 中填充,然后再使用 virtuals。

    要了解更多关于 mongoose virtuals 的信息:https://mongoosejs.com/docs/tutorials/virtuals.html

    希望这会有所帮助

    【讨论】:

      猜你喜欢
      • 2012-03-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多