2012-04-13 25 views
0

我想在mongdb中存儲一些非常大的整數,正好(幾千個十進制數字)。這當然不適用於BSON支持的標準類型,我想要考慮最優雅的解決方法,因爲我想執行範圍搜索和類似的事情。此要求不包括將整數存儲爲字符串,因爲它會使範圍搜索不切實際。bson數組如何比較(在mongodb/pymongo中)?

我可以想到的一種方法是使用標準整數的(可變長度)數組對編碼2^32-擴展進行編碼,並向該數組中添加第一個數組長度的條目。這樣,這些數組上的字典排序對應於任意大整數的通常排序。

例如,集合中我能有5個文檔

{"name": "me", "fortune": [1,1000]} 
{"name": "scrooge mcduck", "fortune": [11,1,0,0,0,0,0,0,0,0,0,0]} 
{"name": "bruce wayne","fortune": [2, 10,0]} 
{"name": "bill gates", "fortune": [2,1,1000]} 
{"name": "francis", "fortune": [0]} 

因此布魯斯·韋恩的身家爲10 * 2^32,比爾·蓋茨的2^32 + 1000和史高治·麥克老鴨的2^320。

那麼我就可以做使用排序{「財富」:1}和我的機器上(與pymongo)返回它們的順序弗朗西斯<我<法案<布魯斯<守財奴,符合市場預期。

不過,我做的是我還沒有看到任何相關文檔有關的方式BSON陣列比較假設和範圍搜索似乎不工作,我認爲(例如道路,

find({"fortune":{$gte:[2,5,0]}}) 

沒有返回任何文件,但我希望布魯斯和史克魯奇)。

任何人都可以幫助我嗎?謝謝

+0

Dhruv和Remon下面描述的兩種解決方案都要求我知道最大長度,並且存儲大量填充零。 – user1199915 2012-04-13 12:13:30

回答

0

你可以改爲存儲左填充的字符串,代表精確的整數等於財富。

eg. "1000000" = 1 million 
    "0010000" = 10 thousand 
    "2000000" = 2 million 
    "0200000" = 2 hundred thousand 

左填充零將確保這些字符串的詞彙比較直接對應於它們作爲數字值的比較。你將不得不 承擔財富的安全最大可能值這裏,說一個20位數字,並 墊0相應 所以樣本文件將是:

{"name": "scrooge mcduck", "fortune": "00001100000000000000" } 
    {"name": "bruce wayne", "fortune": "00000200000000000000" } 

查詢:

> db.test123.find() 
{ "_id" : ObjectId("4f87e142f1573cffecd0f65e"), "name" : "bruce wayne", "fortune" : "00000200000000000000" } 
{ "_id" : ObjectId("4f87e150f1573cffecd0f65f"), "name" : "donald", "fortune" : "00000150000000000000" } 
{ "_id" : ObjectId("4f87e160f1573cffecd0f660"), "name" : "mickey", "fortune" : "00000000000000100000" } 


> db.test123.find({ "fortune" : {$gte: "00000200000000000000"}}); 
{ "_id" : ObjectId("4f87e142f1573cffecd0f65e"), "name" : "bruce wayne", "fortune" : "00000200000000000000" } 


> db.test123.find({ "fortune" : {$lt: "00000200000000000000"}}); 
{ "_id" : ObjectId("4f87e150f1573cffecd0f65f"), "name" : "donald", "fortune" : "00000150000000000000" } 
{ "_id" : ObjectId("4f87e160f1573cffecd0f660"), "name" : "mickey", "fortune" : "00000000000000100000" } 

當mongodb比較字符串時,查詢/排序會自然地工作。 但是,要對數據執行其他數字操作,您必須在數據處理腳本(PHP,Python,Ruby等)中編寫自定義邏輯

對於查詢和數據存儲,此字符串版本應該可以。

0

不幸的是,你對數組比較的假設是不正確的。例如,查詢小於3({array:{$ lt:3}})的所有數組值的範圍查詢將返回至少一個元素小於3的所有數組,而不管元素的位置如何。因爲你的方法不行。

什麼工作,但不太明顯,是使用二進制斑點爲您的大型整數,因爲這些都是字節順序比較。這要求你爲整數設置一個高位限制,但這應該相當簡單。

db.col.find({fortune:{$gt:BinData(0, "e8MEnzZoFyMmD7WSHdNrFJyEk8M=")}}) 

因此,所有你所要做的就是創建方法,你的大整數,比如說,從字符串轉換爲雙二進制的補充和你:你可以使用BinData(亞型,BASE64)符號在外殼測試'重啓。祝你好運