1

私は MongoDB を初めて使用し、いくつかの基礎を試してみましたが、これには驚きました。中心的な概念を誤解していると思いますが、ここで何が起こっているのか誰か教えてもらえますか?

公式の MongoDB C# ドライブを使用して、これらのドキュメントの 10,0000 個を「ロット」と呼ばれる db コレクションに挿入しました。

         // Insert some test data
         const double price = 29.99;
         var bsonDoc = new BsonDocument { 
            {"glossary", new BsonDocument {
                    {"title", "example glossary"},
                    {"GlossDiv", new BsonDocument {
                        {"title", "S"},
                        {"price", new BsonDouble(price)},
                ...
                /* full doc chunk removed here for brevity */
                ...
            };
            ...
                         const int numObjects = 10000;
         for (int i = 0; i < numObjects; i++)
             col.Insert(new BsonDocument(bsonDoc));

            ...

C# ドライバーで見たものを信じられなかったので、シェルでこれを試しましたが、結果は同じです。

db.lots.group({key:{"glossary.GlossDiv.title":true}, reduce:function(obj,out){out.total+=obj.glossary.GlossDiv.price;}, initial:{total:0 } }) [ { "glossary.GlossDiv.title" : "S", "合計" : 299899.99999995757 } ]

私が間違っている場合は修正してください

4

1 に答える 1

3

私が間違っている場合は修正してください。

あなたのデータには 29.99 が含まれていませんでした。ここを見て:

const double price = 29.99;

これは、29.99に最も近い値にprice等しく設定されます。それ29.99 ではありません。正確には、値は 29.989999999999998436805981327779591083526611328125 です。double

これは、Mongo とは関係がありません。これは、バイナリ浮動小数点を使用するための基本です。Mongo が をサポートしている場合はdecimal、代わりにそれを財務値に使用する必要があります。私が期待していたようなものは何も見えBsonDecimalません。それができない場合は、代わりにスケーリングされた整数として値を保存することをお勧めします-たとえば、ドルの数の代わりにセントの数を保存します。

詳細については、 2 進浮動小数点10 進浮動小数点に関する私の記事を参照してください。

于 2012-03-29T16:34:23.883 に答える