2013-06-06 2 views
0

Позвольте мне объяснить проблему. Я использую узел-MongoDB-родной, как драйвер MongoDB и каждый раз, когда мне нужно, чтобы найти запрос на поле _ID я должен преобразовать его в ObjectId как следующее:Неплохая идея использовать пользовательские pk как строку?

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

Строка будет использовать больше места в индексе, также я могу себе представить, что это будет меньше peformant, на самом деле не так много преимуществ, кроме как вы можете запросить без обертывания всего в 'ObjectId' – Sammaye

+0

Ok. Возможно ли предотвратить листинг ObjectId в каждом запросе? – Erik

+0

Хм, возможно, вы могли бы создать расширенный класс 'model', который в своих функциях поиска обнаруживает, если вы ищете' _id', и если вы отбрасываете его в ObjectId – Sammaye

ответ

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 } 

Я нахожусь думая о том, чтобы представить ошибку.

Ситуация еще стоит с 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, но будьте осторожны.

+0

Но как я могу гарантировать уникальность номеров? – Erik

+0

Это немного сложнее, я бы сделал с удобной временной отметкой Unix и последовательностью. На основе нагрузки, которую вам нужно обслуживать. С несколькими клиентом приложения также должен быть включен уникальный идентификатор клиента. С этим вы в конечном итоге с той же логикой, что и манго, это внутренне. Поэтому я не уверен, что это будет быстрее. – attish

+0

Я думаю, что это может быть связано с js больше, чем с MongoDB – Sammaye

 Смежные вопросы

  • Нет связанных вопросов^_^