2013-05-03 48 views
1

我在文檔中有一個字典字段。MongoDB查詢:在字典元素內部過濾

「國家」領域的樣本文件:

... 
"countries": { 
    "us": { 
     "uid": "725129b4-debe-47dc-9ab0-aa8aa620e35b" 
    }, 
    "canada": { 
     "uid": "83250bc5-49ae-4775-a933-d7a3e9d00d1c" 
    }, 
    "uk": { 
     "path": "/uk/", 
     "uid": "e32347a9-522c-4c66-be3b-3edfd50c76bb" 
    }, 
    "spain": { 
     "path": "/spain/", 
     "uid": "93ecd56b-1ed2-4647-bee8-8685183eca2e" 
    }, 
    "india": { 
     "path": "/india/", 
     "uid": "c4458535-c63b-45e1-bb24-cabbc65d59a4" 
    } 
} 
... 

從我需要得到具有「路徑」國家所有文件屬性存在?

+1

快速問題:你可以把'countries'轉換成一個字典數組,例如'[{'key':'us','uid':'725129b4-debe-47dc-9ab0-aa8aa620e35b' },{'key':'canada',...} ...]'?在這種情況下構建查詢會容易得多。 – alecxe 2013-05-03 14:11:01

+0

我明白它可以幫助,但我不能那樣做,它被用在許多地方。現有的結構適合我們的需求 – Neo 2013-05-03 14:20:40

回答

0

雖然更改數據結構將是最好的選擇(因爲查詢效率更高,不需要二級集合 - 甚至在保存文檔時甚至可以雙重存儲它)可以嘗試一個MapReduce來獲得結果,如果你不能改變你的數據結構。您可能需要進行增量更新,並注意結果可能並不總是最新的。

下面是一個簡單的版本(在JavaScript):

map = function() { 
    // loop through the countries node 
    if (this.countries) { 
     for(var name in this.countries) { 
      if (typeof this.countries[name].path !== 'undefined') { 
      // emit a unique combo id so that the reduce will only have 
      // one value to reduce later 
      emit({id: this._id, country: name}, this.countries[name].path); 
      } 
     } 
    } 
}; 

reduce = function(key, values) { 
    // return the one value 
    return values; 
}; 

然後,運行減少:

db.so.mapReduce(map, reduce, {out: "so_map"}) 

可生產類似(給你的樣本數據):

> db.so_map.find() 
{ "_id" : { "id" : ObjectId("5183e08be71ddfd99756386c"), "country" : "india" }, "value" : "/india/" } 
{ "_id" : { "id" : ObjectId("5183e08be71ddfd99756386c"), "country" : "spain" }, "value" : "/spain/" } 
{ "_id" : { "id" : ObjectId("5183e08be71ddfd99756386c"), "country" : "uk" }, "value" : "/uk/" }