1

我在 MongoDb 中有一个数据库,其中包含两个集合:“类别”和“文章”。我在 NodeJs 上使用 Mongoose 连接到数据库并读取类别。我想在不发出额外请求/查询的情况下计算一个类别的文章数量,所以如果我能在数据库级别解决这个问题就完美了。

“类别”集合中的项目如下所示:

{
'_id' : ObjectId("..."),
'feed_id' : 1,
'name': 'Blog posts'
}

“文章”集合中的项目如下所示:

{
'_id' : ObjectId("..."),
'feed_id' : 1,
'title': 'Article title',
'published' : '12/09/2012',
...
}

因此类别和文章使用“feed_id”字段链接。

我想导出所有类别以及相应数量的文章:

{
'_id' : ObjectId("..."),
'feed_id' : 1,
'name': 'Blog posts',
'no_articles': 4
}

我不确定我应该如何做到这一点:

1)在类别集合中创建一个“no_articles”字段?如果是,我希望在从文章集合中插入或删除文档时自动更新。

2)阅读分类时将文章总结为'no_articles'?

我读了一些关于 MapReduce 和 group 的东西,但不太明白是否可以将它们用于这个特定的任务。

4

2 回答 2

1

这是传统关系数据库真正大放异彩的用例之一。

在 mongodb 中使用一个查询是不可能做到这一点的。您提到的“no_articles领域”是要走的路。这种方法的通用名称(无论如何,在 Rails 人中)是:Counter Cache Column. 我对 Mongoose 不是很熟悉,所以我不知道它是否会为您保留该字段。MongoDB 本身当然不会这样做。但是自己维护它并不是很多工作,你只需要准确。

我建议不要在阅读类别时计算文章。这是一个典型的N+1 query问题示例,计数器缓存列可以防止它发生。

于 2012-10-03T10:49:48.113 回答
0

为什么不直接将类别存储在 post 文档中?由于您似乎正在为每个使用该类别的帖子创建新的类别文档(如使用 feed_id 的一对多链接所证明的那样),因此在帖子文档中存储一个类别数组可能是有意义的。

{
'_id' : ObjectId("..."),
'feed_id' : 1,
'title': 'Article title',
'published' : '12/09/2012',
...
categories : [ 'Blog Posts', 'Category 2' ]
}

然后你可以做一个

db.articles.find({categories : 'Blog Posts' })

要查找具有特定类别的所有文章,您可以添加一个 .count() 来获取计数

使用这些 feed_ids 加入是 MongoDB 的诅咒。您不能跨集合加入,因此您必须非规范化或将所有内容放在一个大集合中。Mongo 的设计目的是让您对所有内容进行非规范化。

如果这似乎不是解决问题的正确方法,那么您可能更适合使用 RDBMS。

于 2012-10-03T21:34:36.500 回答