让我解释一下这个问题。我使用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。但我不知道它将如何影响查询性能。
请问您告诉我这种方法有哪些优点和缺点?
答案 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的数字,但要小心。