除了在MongoDB中为Blog-Tag系统嵌套标签数组之外,还有什么方法吗?

时间:2012-10-05 16:30:25

标签: node.js mongodb nosql

我正在尝试使用node.js / express / mongodb为自己编写博客引擎(也是开始学习node.js)。为了比互联网上的教程更进一步,我想为博客引擎添加标签支持。

我想用标签做以下事情:

  1. 观看者可以在“标签云页面”上看到所有标签为标签云
  2. 观看者可以在文章列表页面和单个文章页面上看到文章的标签
  3. 观看者可以点击单个标签来显示文章列表
  4. 此外,观众还能够以SO方式搜索带有特定标签的文章:[tag1] [tag2] - > / tags / tag1 + tag2 - >同时包含tag1和tag2
  5. 的文章列表

    在关系数据库中,将使用post_tag表。但是如何在MongoDB中设计它?

    我查了MongoDB design - tags
    但正如efdee评论,设计

    db.movies.insert({
      name: "The Godfather",
      director: "Francis Ford Coppola",
      tags: [ "mafia", "wedding", "violence" ]
    })
    

    有问题:

      

    这似乎没有真正回答他的问题。您将如何获得整个电影收藏中使用的不同标签列表?

    这也是我的关注:在我的设计中,我需要显示所有标签的列表;我还需要知道每个标签有多少篇文章。那么有比上面显示的设计更好的方法吗?

    我对上述设计的关注是:如果我想显示标签列表,查询将遍历数据库中的所有文章项。有更有效的方法吗?

3 个答案:

答案 0 :(得分:2)

您需要在标签上创建一个多键索引才能开始。

然后,您将能够使用此语法找到文档匹配标记

db.movies.find({ "tags": { $all : [ /^this/, /^that/ ] }})

因为你正在使用reg ex mongo的^(字符串的开头)仍然会使用索引。

要获得关键字密度,使用聚合框架,您可以简单地计算。

db.movies.aggregate({ $project: { _id:0, tags: 1}}, 
    { $unwind: "$tags" },
    { $group : { _id : "$tags", occur : { $sum : 1 }}})

抱歉iPad的格式很难。

您最终会收集如下文档的文档:

{
   _id: "mytag",
   occur: 383
},
{
   _id: "anothertag",
   occur: 23
},

使用aggregate命令可以获得内联结果,因此如果经常使用结果,则可以使用客户端应用程序(或服务器)来序列化或缓存结果。

让我知道你是如何继续这样做的。

Hth

萨姆

答案 1 :(得分:0)

您将如何获得整个电影收藏中使用的不同标签列表?

db.movies.distinct("tags")

为了有效查询,我可能会复制数据。标签不太可能被编辑,所以我将标签数组放在文章对象中,然后将标签放在标签集合中,标签包含包含该标签的文章计数或文章数组IDS。

db.movies.insert({
  id: 1,
  name: "The Godfather",
  director: "Francis Ford Coppola",
  tags: [ "mafia", "wedding", "violence" ]
});

db.tags.insert([
   {name: "mafia", movie_count: 1},
   {name: "wedding", movie_count: 1},
   {name: "violence", movie_count: 1}
});

答案 2 :(得分:-1)

您可以使用MapReduce函数执行4个任务。例如,对于所有标签的列表,您将标签作为键发出,然后在reduce函数中,您将全部计数并返回计数。这将是我走下去的路线。它可能需要更多的思考,但它绝对是强大的。

http://cookbook.mongodb.org/patterns/count_tags/