2012-07-09 68 views
0

現在,我們使用mongodb 1.2.2來創建數據庫和存儲值。我們的數據類型是這樣的:Mongodb:通過多個相對未知的鍵值查詢

"file" : "1" , "tools": { "foo": { "status": "pending"} } 
"file" : "2" , "tools": { "bar": { "status": "pending" } } 
"file" : "3" , "tools": { "foo": { "status": "running" } } 
"file" : "4" , "tools": { "bar": { "status": "done" } } 
"file" : "5" , "tools": { "foo": { "status": "done" } } 

我們要查詢每一個{ "status" : "pending" }.我們不希望使用{"tools.foo.status" : "pending"},因爲我們將有超過foo和酒吧等許多不同的變化。爲了更清楚我們想要做這樣的事情{"tools.*.status" : "pending"}

+1

1.2.2?真的嗎?沒有錯字? – 2012-07-09 20:53:23

+0

您要求的內容不存在。你可以用map-reduce或者把函數傳給'where'來解決這個問題。這兩者都不是高性能的。您也可以在其他地方將您的數據包含在易於搜索的地方。 – Travis 2012-07-09 20:55:06

+0

好吧......聽起來很難。是的,我們很可能很快就會升級。 – 2012-07-09 20:56:49

回答

1

不,你不能這樣做。恐怕你必須爲此維護你自己的索引。也就是說,對於每個對文件集合的插入/更新,對file_status_index集合執行upsert以更新當前狀態。

查詢也是一個兩步過程:首先查詢索引集合以獲取ID,然後向文件集合發出查詢以獲取實際數據。

這聽起來很可怕,但這是你必須用這個模式支付的代價。

0

我想是時候問爲什麼你正在存儲東西的方式。

沒有有效的方法來搜索這種結構;由於沒有已知的按鍵路徑可以達到要過濾的值,因此每一次記錄都需要每次擴展,這非常昂貴,特別是一旦您的集合不再適合RAM時。

國際海事組織,你最好用二次收集來保存這些狀態。是的,它使您的數據存儲更具關聯性,但這是因爲您的數據關係。

file_tools: 
    { 'file_id' : 1, 'name' : 'foo', 'status' : 'pending' } 
    { 'file_id' : 2, 'name' : 'bar', 'status' : 'pending' } 
    { 'file_id' : 3, 'name' : 'foo', 'status' : 'running' } 
    { 'file_id' : 4, 'name' : 'foo', 'status' : 'done' } 
    { 'file_id' : 5, 'name' : 'foo', 'status' : 'done' } 


files: 
    { 'id': 1 } 
    { 'id': 2 } 
    { 'id': 3 } 
    { 'id': 4 } 
    { 'id': 5 } 

> // find out which files have pending tools 
> files_with_pending_tools = file_tools.find({ 'status' : 'pending' }, { 'file_id' : 1 }) 
> //=> [ { 'file_id' : 1 }, { 'file_id' : 2 } ] 
> 
> // just get the ids 
> file_ids_with_pending_tools = files_with_pending_tools.map(function(file_tool){ 
> file_tool['file_id'] 
> }) 
> //=> [1,2] 
> 
> // query the files 
> files.find({'id': { $in : file_ids_with_pending_tools }}) 
> //=> [ { 'id' : 1 }, { 'id' : 2 } ] 
+0

現在,我們只在每個字典中有一個項目,但有不止一個......所以我沒有看到更好的方法 – 2012-07-09 21:01:00

1

首先,你應該升級你的MongoDB。 1.2.2真的是舊版本。

其次,你不能做查詢你問。您可以使用Map/Reduce.