2012-04-13 4 views
0

私はmongdbにいくつかの非常に大きな整数を正確に(数千の10進数)格納したいと思います。これはもちろんBSONでサポートされている標準タイプでは機能しません。範囲検索などを実行したいと考えて、最も洗練された回避策を考えています。この要件は、範囲検索を非実用的にするので、文字列としての整数の格納を除外します。bson配列はどのように(mongodb/pymongoで)比較されますか?

私が考えることの1つの方法は、標準のintの(可変長)配列を使用して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]} 

を持つことができますこのようにブルース・ウェインの純資産は、ビル・ゲイツ2^32 + 1000とスクルージ・マクダックの2^320、10 * 2^32です。

私は、使用してソートを行うことができます{「幸運を」:1}と私のマシン上で(pymongoで)予想通り、それは、順番フランシス<私<法案<ブルース<スクルージでそれらを返します。

しかし、私はBSONアレイを比較する方法についてはどこにも文書化、および範囲検索は、私が(例えば、

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

だと思うように動作していないようです見ていない仮定を作っています文書は返されませんが、私はブルースとスクルージを望みます)。

誰でも手伝ってもらえますか?ありがとう

+0

以下のDhruvとRemonによって説明されている解決方法では、最大長を知っていなければならず、たくさんのパディングゼロを保存する必要があります。 – user1199915

答えて

0

代わりに、fortuneに等しい正確な整数を表す左パッド付き文字列を格納できます。

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

ゼロを左に埋め込むことで、これらの文字列の字句比較が数値としての比較にも直接対応するようになります。

{"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" } 
あなたは サンプル文書は次のようになりそう に応じて0を、ここで幸運の安全な可能な最大値を取る20桁の番号を言うと、 パッドになります

mongodbは文字列を字句解析と比較するので、クエリ/ソートは自然に機能します。 しかし、データに他の数値演算を行うには、データ処理スクリプト(PHP、Python、Rubyなど)にカスタムロジックを記述する必要があります。

この文字列バージョンは問題ありません。

0

残念ながら、配列の比較についてのあなたの前提は正しくありません。たとえば、3より小さいすべての配列値({array:{$ lt:3}})をクエリする範囲クエリでは、要素の位置に関係なく、少なくとも1つの要素が3未満のすべての配列が返されます。あなたのアプローチは機能しません。

非常に大きな整数にはバイナリブロブを使用していますが、これはバイトオーダーの比較であるため、動作はしませんが、あまり明確ではありません。そのためには、整数の上限ビット数を設定する必要がありますが、それはかなり簡単です。だから、あなたがしなければならないだろうすべては、二補完バイナリに、文字列、たとえば、からあなたの大きな整数に変換するメソッドを作成している

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

とあなた:あなたはBINDATA(サブタイプ、BASE64)表記を使用して、シェルでそれをテストすることができます再設定される。幸運

関連する問題