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,这有点奇怪,但它不应该与十进制表示相关(实际上 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 回答