2010-09-15 28 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" ] }