0

問題を説明しましょう。node-mongodb-native を mongodb ドライバーとして使用し、_id フィールドで検索クエリを作成する必要があるたびに、次のように ObjectId に変換する必要があります。

var ObjectID = require('mongodb').ObjectID;

db.collection.find({_id: new ObjectID('51b02413453078800a000001')}, 
       function (err, docs) {
           ...
       });

リクエストごとに ObjectID にキャストしたくありません。これまでに見つけた唯一の解決策は、次のような文字列としてカスタム ObjectID を生成することです。

var CustomPKFactory = {
   createPk: function() {
    return new ObjectID().toString();
   }
};

var mongoClient = new MongoClient(new Server('localhost', 27017), {   
   pk: CustomPKFactory,
});

この場合、_id を文字列として持つことになり、それをそれぞれ ObjectID に変換する必要はありません。しかし、それがクエリのパフォーマンスにどのように影響するかはわかりません。

このアプローチの長所と短所を教えてください。

4

1 に答える 1

0

デフォルトでは、Sammaye がコメントで説明したように、文字列のサイズは大きくなります。それを形式化するには:

Object.bsonsize({ "_id" : ObjectId("51b10b55f202d3fee925d637")}) = 22 
Object.bsonsize({ "_id" : "51b10b55f202d3fee925d637"}) = 39
Object.bsonsize({ "_id" : "aaaaaaa"}) = 22
Object.bsonsize({ "_id" : 9999999999999998 }) = 18

したがって、7 文字の長さの文字列は、ObjectId と同じサイズになります。使用する数値が小さい場合は、次のことを考慮する必要があります。

数値の型間の変換が自動であるというmongoshellでの入力は自動ですが、本当に興味深いことがわかりました。したがって、基本的に、「整数」(少なくとも形式) として保存できる最大の数値は 9999999999999998 ですが、これは少し奇妙ですが、10 進数表現とは関係ありません (実際、BSON データ型は Double です)。上記のすべての数値は、次のように自動的に変換され、通常の形式に丸められます。

{_id:9999999999999999} 

として保存されます:1e + 16.0および丸められた値なので、挿入しようとすると:

insert({_id:10000000000000001})
E11000 duplicate key error index: $_id_  dup key: { : 1e+16.0 }

バグを提出しようと考えています。

64 ビット整数の BSON 型である NumberLong() 型を使用する価値のある状況です。

> db.m.insert({_id: NumberLong(10000000000000001)})
E11000 duplicate key error index: t.m.$_id_  dup key: { : 10000000000000000 }
> db.m.insert({_id: NumberLong(10000000000000002)})
> db.m.insert({_id: NumberLong(10000000000000003)})
> db.m.insert({_id: NumberLong(10000000000000004)})
E11000 duplicate key error index: t.m.$_id_  dup key: { : 10000000000000004 }
> db.m.insert({_id: NumberLong(10000000000000005)})
E11000 duplicate key error index: t.m.$_id_  dup key: { : 10000000000000004 }
> db.m.insert({_id: NumberLong(10000000000000006)})
> db.m.insert({_id: NumberLong(10000000000000007)})
> db.m.insert({_id: NumberLong(10000000000000008)})
E11000 duplicate key error index: t.m.$_id_  dup key: { : 10000000000000008 }
> db.m.insert({_id: NumberLong(10000000000000009)})
E11000 duplicate key error index: t.m.$_id_  dup key: { : 10000000000000008 }

そのため、ObjectId よりもストレージ サイズが小さい数値を使用できますが、注意が必要です。

于 2013-06-07T08:31:32.587 に答える