2014-09-29 127 views
0

我有一個非常大的集合(超過800k),我需要實現基於標籤的自動完成(基於單詞開頭)功能的查詢。我的文件是這樣的:mongodb快速標籤查詢

{ 
    "_id": "theid", 
    "somefield": "some value", 
    "tags": [ 
     { 
      "name": "abc tag1", 
      "vote": 5 
     }, 
     { 
      "name": "hij tag2", 
      "vote": 22 
     }, 
     { 
      "name": "abc tag3", 
      "vote": 5 
     }, 
     { 
      "name": "hij tag4", 
      "vote": 77 
     } 
    ] 
} 

舉例來說,如果我的查詢將是與「AB」開頭,並有一個「somefield」,即「一些價值」的結果將是「ABC標籤1」的標籤, 「abc tag3」(僅限名稱)。 我關心查詢的速度遠遠超過插入和更新的速度。

我認爲聚合框架將會是正確的方式,但是對於非常快速的查詢,最好的管道和索引是什麼?

這些文檔不是'標籤'文檔,它們是代表客戶端對象的文檔,它們包含更多的數據字段,爲了簡單起見我省略了每個客戶端有幾個標籤和另一個字段(我更改了它的名稱,所以它不會是與標籤數組混淆)。我需要獲得一組沒有一組客戶端所有標籤的重複內容。

+0

我曾嘗試做類似的去年,但數據庫更小。隨着數據量的增長,我最終不得不使用Solr。 – Martin 2014-09-29 18:43:23

+0

你可以發佈你試過的查詢和索引嗎?你使用聚合框架嗎? – jacob 2014-09-29 19:28:15

+0

對不起,代碼已經過去了,但它是基於標記字段上的正則表達式。它預先聚合框架,但我不知道這將是最好的方法。根據我的經驗,聚合框架喜歡將整個文檔讀入內存,即使$匹配只能使用索引 – Martin 2014-09-30 08:47:35

回答

0

你的文檔結構沒有意義 - 我假設tags是一個數組而不是一個對象。嘗試像這樣的查詢

db.tags.find({ "somefield" : "some value", "tags.name" : /^abc/ }) 

索引{ "maintag" : 1, "tags.name" : 1 }。 MongoDB將左錨定正則表達式查詢優化爲範圍查詢,這可以使用索引高效地實現(請參閱$regex docs)。

你可以只使用一個聚合管道從這個文檔結構標籤:

db.tags.aggregate([ 
    { "$match" : { "somefield" : "some value", "tags.name" : /^abc/ } }, 
    { "$unwind" : "$tags" }, 
    { "$match" : { "tags.name" : /^abc/ } }, 
    { "$project" : { "_id" : 0, "tag_name" : "$tags.name" } } 
]) 

指數不僅有助於爲第一$比賽,所以相同的索引管道作爲查詢。

+0

您是對的我的對象有錯誤,我修正了它。您的查詢將返回所有符合條件的文檔,我只需要一個無重複的標籤列表。否則我將獲取所有不必要的數據。 – jacob 2014-09-30 15:26:01

+0

$位置操作符可以輸出1個匹配的標籤。如果你確實需要返回所有標籤,那麼你已經不適當地構建你的文檔。這些文檔應該是主標籤非標準化的標籤,而不是帶有標籤的主標籤文檔。 – wdberkeley 2014-09-30 17:44:55

+0

我想我的問題並不清楚,請參閱我的編輯。它不是一個標籤文檔,它是一個帶有嵌套的士氣低落的標籤陣列的客戶端文檔。 – jacob 2014-09-30 18:19:44