将自定义pk用作字符串是不错的主意?

时间:2013-06-06 06:38:27

标签: node.js mongodb mongodb-query node-mongodb-native

让我解释一下这个问题。我使用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。但我不知道它将如何影响查询性能。

请问您告诉我这种方法有哪些优点和缺点?

1 个答案:

答案 0 :(得分:0)

默认情况下,Sammaye在评论中描述的字符串大小会更大。正式化它:

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

所以一个7 char长的字符串与ObjectId的大小相同。如果你使用的数字较小,但你必须考虑这个:

我发现在mongoshell中自动输入时,真正有趣的是数字类型之间的转换是自动的。所以基本上你可以存储为“整数”(至少是格式)的最大数字是9999999999999998这有点奇怪,而它不应该与小数表示有关(实际上BSON数据类型是Double)。以上所有数字都会自动转换并舍入为普通形式,例如:

{_id:9999999999999999} 

将存储为:1e + 16.0并且它是一个舍入值,因此当您尝试插入时:

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

我正在考虑提交错误。

这种情况甚至值得使用NumberLong()类型,它是64位整数BSON类型:

> 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的数字,但要小心。