使用ObjectID引用实现RESTful Mongoose

3

我的问题:如何使用MongooseJS创建一个RESTful的MongoDB实例,而不需要进行大量的HTTP请求?

我的设置:我正在使用NodeJS作为后端,并使用MongooseJS。在前端,我使用AngularJS,因此我决定使用angular-bridge来将我的MongoDB数据库转换为RESTful API。

我的模式:我有以下模式:

Schemas

注意:箭头的起点表示该对象引用了箭头末端的对象(例如,comment具有一个owningPost属性,该属性是指向post的ObjectID引用)。另外,星号(*)表示“多个”,因此,一个post可以有许多comments,但是一个comment只引用一个post,一个stream可以引用许多buckets,而一个bucket可以有许多streams引用它。
问题:假设用户点击代表bucket的页面。我需要进行以下获取请求:
1. Bucket 2. User 3. 引用bucket的每篇post 4. 引用post的每个comment 5. 每个comment的用户
请注意,请求的数量可能会迅速增加。也许我可以将comment包含在post中,这可能不是问题。然而,对于其他所有内容(并保持理智),我无法这样做。
我尝试创建一个端点,以获取不同属性中的所有数据,例如:
data: {
  bucket: {},
  user: {},
  posts: [
    {
      post: {},
      comments: [
        user: {},
        comment: {}
      ]
    }
  ]
}

但这样就不再是RESTful了,对吧?这会使更新内容变得有些困难。
我做错了什么?有更好的方法吗?

如果您的数据和需求符合关系模型,您可以考虑使用关系数据库而不是MongoDB。 - Hector Correa
3个回答

2
我通常的做法是:
  • 在“列表”请求中不填充任何内容。
  • 在“展示”请求中填充所有objectId引用。
就我而言,这并不会使您的服务不那么RESTful。它仍然是面向资源的,所附带的数据实际上属于特定的资源。这应该可以减少您需要进行的请求数量。
或者,您可以创建一个容器资源,收集所有必需的信息并将其发送回客户端。不过,我个人会选择几个单独的请求。特别是因为自HTTP 1.1以来,多个请求可以通过同一连接执行。我认为在同一时间请求多个JSON对象对您的应用程序性能没有任何显着影响。
但我不会把所有东西都嵌套在“data”模式内。
希望这有所帮助,祝你好运!

我越想这个想法,就越喜欢它。我想我会采用它。我会在尝试并了解结果后告诉你。 - kentcdodds
@kentcdodds 我很高兴你喜欢这个想法,是的,请做吧! - Synzvato Chavea
好的,所以这个工作得很好。即使我没有完全按照你的实现方式,你真的帮助我克服了这个问题。我的做法是在获取流的帖子时实际上返回一个“数据”对象,但我为适当的数据创建了一个$resource对象,然后将该对象简单地附加到它所属的资源上。这不会被持久化到数据对象中。因此,基本上,当我加载一个帖子时,它有一个评论属性,所以我为每个评论创建/替换一个资源,然后我对评论的作者也是同样的处理。这样我就可以获得RESTful的好处,并减少请求次数。 - kentcdodds

1
对我来说,这更像是一个面向文档的数据设计问题,而不是一个REST设计问题。我的方法是通过视图或页面驱动数据模型的设计,而不是先设计模型,然后尝试将视图适配到它上面。这在某种程度上与Reda的答案相一致。
为了减少请求数量或mongoose populations,我总是允许文档中出现重复。在你的例子中,一个bucket将有一个帖子id数组和一个流id数组。同时,一个帖子将有一个buckets id数组,甚至还有每个bucket的一些详细信息。这样的设计将使文档的检索非常快,但会降低更新操作的速度,并且也会引入不一致性的风险。

0

你应该对模式进行反规范化处理


我意识到规范化模式不是“MongoDB方式”,但是如果没有规范化模式,您会如何推荐表示多对多的关系? - kentcdodds
我会将网页上显示的所有数据存储在一个单独的文档中。 - Reda
我猜我没有很好地解释我如何使用这些数据。因为一篇帖子可以在多个桶中,而一个桶也可以有多个帖子,你会建议将另一个文档存储在哪里?无论哪种方式都不合理...至少对我来说是这样。我错了吗? - kentcdodds
你仍在关系术语中推理。你的用例是什么?你如何显示和编辑这些数据? - Reda
可以有一个帖子页面,仅显示特定的帖子及其评论。可以有一个桶页面,其中显示该桶中的所有帖子/评论。还可以有一个流页面,其中显示所有桶和所有流桶中的所有帖子/评论。 - kentcdodds
4
你考虑过使用关系型数据库吗?所有的数据库都有它们适用的场景。 - winduptoy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接