2010-09-15 24 views
6

链接具有一个或多个标签,所以在一开始似乎自然地嵌入标签:如何在MongoDB中有效地实现这些查询?

link = { title: 'How would you implement these queries efficiently in MongoDB?' 
     url: 'http://stackoverflow.com/questions/3720972' 
     tags: ['ruby', 'mongodb', 'database-schema', 'database-design', 'nosql']} 

如何将这些查询能够高效地实现?

  • 包含一个或多个给定的标签(用于搜索与特定标记的链接)
  • 获取所有标签的列表,但不重复(搜索框自动完成)获得链接
  • 获取最热门的标签(显示顶部10的标签或标签云)

到表示与上述是基于MongoNY presentation链路的想法,滑动38.

回答

4

获取包含“值”的标签链接:

db.col.find({tags: "value"}); 

包含 “VAL1”, “值2” 标签获取链接:所有标签的不重复

db.col.find({tags: { $all : [ "val1", "val2" ] }}); 

获取列表:

db.col.distinct("tags"); 

获取最热门的标签 - 这是不是可以在现有的数据库中查询的东西,你需要做的是每当查询获取文档时添加一个受欢迎字段来更新它,然后在排序字段设置为受欢迎度的情况下执行查询。

更新:提议的解决方案的流行性功能。 尝试添加以下集合,我们称它为标签。

DOC = {标签:字符串,流行:整数}

现在,一旦你做一个查询你收集所有被证明(这些可以汇总和异步完成)的标记,以便让我们说你结束与

以下标签:“tag1”,“tag2”,“tag3”。

然后,您调用Update方法,并增加了流行的字段值:

db.tags.update({tag: { $in: ["tag1", "tag2", "tag3"] }}, { $inc: { pop: 1 }}); 
+0

为了增加人气场的标签,该标签将需要添加或移动到一个单独的收集,正确吗? – randomguy 2010-09-15 19:29:53

+0

你不需要,你可以将它保存在同一个集合中,只需使用dbref指向标签。一个不同的集合会让你更简单地管理你的数据(这是我推荐的)。 – Asaf 2010-09-15 19:38:29

+0

在标签集合中,我建议将标签名称放在_id字段中,而不是使用单独的标签字段。另外,如果您不介意为每个标记执行一次更新而不是使用$ in,则可以仅查询{_id:“tag_name”}并使用upsert功能创建新的标记条目。 – mstearn 2010-09-15 20:19:31

0

您还可以使用$ addToSet更改标签阵列,而不是$推动。当标签已经存在时,这不会修改文档。 如果您经常修改标签,这会更有效率(因为文档不会增长太多)。 下面是一个例子:

> db.tst_tags.remove() 
> db.tst_tags.update({'name':'test'},{'$addToSet':{'tags':'tag1'}}, true) 
> db.tst_tags.update({'name':'test'},{'$addToSet':{'tags':'tag1'}}, true) 
> db.tst_tags.update({'name':'test'},{'$addToSet':{'tags':'tag2'}}, true) 
> db.tst_tags.update({'name':'test'},{'$addToSet':{'tags':'tag2'}}, true) 
> db.tst_tags.update({'name':'test'},{'$addToSet':{'tags':'tag3'}}, true) 
> db.tst_tags.find() 
{ "_id" : ObjectId("4ce244548736000000003c6f"), "name" : "test", 
    "tags" : [ "tag1", "tag2", "tag3" ] }