Nosql MongoDB



我正在尝试构建一个应用程序,其中我只有以下3种型号:

  • 主题(只有标题(最多100个字符))
  • comment(具有文本(可能很长)、author_id主题id创建日期)
  • author(只有用户名)

实际上是一个非常简单的数据库结构。一个主题可能有许多评论,这些评论是由作者创建的。作者可能会有很多评论。

我仍在努力找出设计数据库结构(文档)的最佳方法。首先,我想把一切都放在自己的模式中,就像上面一样。3文件。但由于这是一个nosqldb,我实际上应该尝试消除对联接的需求。现在我真的在考虑把所有东西都放在一个单一的文档中,这听起来也很疯狂。

这些是我从ui的实际查询:

  • 主页查询:列出今天收到最多评论的所有主题(将经常运行)
  • 搜索字段的自动建议列表:列出所有主题,其标题包含字符串"X">
  • 主题查询的主页面:列出主题的所有注释及其作者的用户名

由于我的大多数查询都需要来自至少两个文档的数据,我真的应该把它们一起用在一个文档中吗

注释(文本用户名主题标题创建日期)

这样我就不需要任何加入,但也可以多次保存主题的标题。。在每一条评论中。。

我就是不能决定。

我感谢你的帮助。

您可以进行建议的第二种设计,但这一切都取决于您希望如何使用数据。我想你会把它用于一个网站。

如果你希望评论是可点击的,点击主题名称将重定向到主题页面,或者点击用户名将重定向到用户页面,在那里你可以看到他的所有评论,我建议你将其保留为ID。由于您以后可以使用.populate(“field1 field2”),并且可以从该ID中选择您想要获得的字段。

或者,您可以将topic_name和username及其ID存储在同一文档中,以减少查询,但最终会存储更多冗余数据。

修订设计:

三个查询(在问题帖中)可能是这样的(伪代码):

  • 从评论中选择所有主题,其中日期为今天,按主题分组并计数评论,按计数排序(desc)
  • 从评论中选择主题,主题与搜索匹配,按主题分组
  • 从注释中选择all,其中主题与topicparam匹配,按注释日期(desc)排序

所以,正如你(在你的问题帖子中)所预期的那样,很可能会有一个主要的集合,comments

评论:

date
author
text
topic

用户和主题集合各有一个字段,是可选的,以保持唯一性。

请注意,按查询分组将是聚合查询,例如,主查询如下所示:

db.comments.aggregate( [
{ $match: { date: ISODate("2019-11-15") } },
{ $group: { _id: "$topic", count: { $sum: 1 } } },
{ $sort: { count: -1 } }
] )

这将给你所有的主题名称,今天和最高计数的主题第一。

您也可以采取一些不同的方法。在所有情况下,存储冗余信息并不是一件坏事。

1.主页查询:列出今天收到最多评论的所有主题(将经常运行)

您可以将其实现为Topic实体中的两个额外字段。一个描述了最后一次添加评论的日期,另一个统计当天添加的评论数量。通过这样做,您不需要加入,但可以编写一个只查看Topic集合的查询。

您还可以独立于其他数据存储这些统计信息,并在需要时进行更新。可以将其视为拥有一个描述数据库当前状态的文档(至少是与您相关的部分)。

这可能会使您在存储信息时受到时间限制,但会提高阅读时间。

2.搜索字段的自动建议列表:列出所有主题,其标题包含字符串"X">

据我所知,你只需要题目。这意味着您可以查询数据库一次并检索所有标题。如果集合增长得如此之大,以至于速度变慢,则可以触发只返回子集的检索查询刷新(用户不太可能浏览100个可能的主题)。

3.主题查询主页面:列出主题的所有评论,以及作者的用户名

这实际上是一个棘手的问题。如果这真的是你想要做的,那么你最好将所有数据存储在一个文档中。然而,我想问您:进行多个查询有什么问题?我怀疑当有数千条评论(正如你所说)时,你是否会同时显示所有评论。与其将每个存储在单独的文档中或将所有存储在一个文档中,您还可以对它们进行bucket处理,只检索20个最新的bucket(如果您要创建大小为20的bucket)。在这里阅读更多关于bucket模式的信息,并在需要时更新显示的内容。

你说:

"由于我的大多数查询都需要来自至少两个文档的数据,我真的应该在这样的单个文档中一起使用它们吗…">

我将从"领域驱动设计"的角度进行论证。假设您的所有数据都存在于同一个有界上下文(业务域)中。那么,将其全部封装在同一文档中是可以接受的!

最新更新