在单个查询中读取类别和文章数量

时间:2012-10-03 10:41:40

标签: mongodb mongoose count grouping

我在MongoDb中有一个包含两个集合的数据库:'categories'和'articles'。 我在NodeJs上使用Mongoose连接到数据库并读取类别。我想计算一个类别的文章数量而不需要额外的请求/查询,所以如果我能在数据库级别解决这个问题,那将是完美的。

'categories'集合中的项目如下所示:

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

'articles'集合中的项目如下所示:

{
'_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的内容,但不太明白是否可以将它们用于此特定任务。

2 个答案:

答案 0 :(得分:1)

这是传统关系数据库真正发挥作用的用例之一。

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

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

答案 1 :(得分:0)

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

{
'_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。