2012-05-15 2 views
0

У меня есть webapp, где я создан встроенный документ для обучения. Документ о работе выглядит примерно так:Встроенный документ MongoDB BSON ID

"educations" : [ 
    { 
     "school" : "Brandywine High School", 
     "major" : "Testingasdf", 
     "grad_year" : ISODate("1979-01-01T00:00:00Z"), 
     "school_type" : "Graduate", 
     "_id" : ObjectId("4fb26c9ce5be08208b000ce4") 
    } 
], 
"email" : "[email protected]", 

Образование hash содержит подробную информацию о работе. Я заметил, что если я создать хэш без ID:

User.collection.update(
    { _id: @user.id }, 
    { :$push => { educations: education } }, 
    { safe: true } 
) 

и я запрашиваю образование из консоли Rails, идентификатор будет меняться каждый раз:

irb(main):004:0> User.brandon.educations.map(&:id) 
=> [BSON::ObjectId('4fb26e13e5be082384000007')] 
irb(main):005:0> User.brandon.educations.map(&:id) 
=> [BSON::ObjectId('4fb26e13e5be082384000009')] 

Однако, если я делаю это:

User.collection.update(
    { _id: @user.id }, 
    { :$push => { educations: BSON::ObjectId.create_pk(education) } }, 
    { safe: true } 
) 

Идентификатор идентичен при каждом запросе с консоли. Из-за этого у меня возникают проблемы со ссылкой на образование, чтобы отредактировать встроенный документ в браузере.

Должен ли я всегда предоставлять BSON ID при создании встроенного документа?

+0

Можете ли вы изменить свой вопрос, чтобы показать весь образец документа? Что вы подразумеваете под «идентификатор будет меняться каждый раз»? Можете ли вы показать пример этого? –

+0

Обновлен документ и методы, используемые для обновления. – user577808

ответ

0

Если вы не укажете какой-либо идентификатор (это может быть строка, int и т. Д.) В поле _id, то MongoDB автоматически создаст его для вас, чтобы сделать документ уникальным (чтобы он мог быть поднятым _id). Обычно существует уникальный индекс на _id, поэтому, если документ не уникален, вставка не будет выполнена (или вместо этого будет обновлен существующий документ и т. Д.).

Стратегия MongoDB для создания документа уникальна в использовании ObjectID, поскольку они уникальны по всему миру. Они также различны каждый раз, когда вы их создаете - так они уникальны во всем мире.

Короче говоря: если у вас есть ключ, который сделает ваш документ 100% уникальным (возможно, школа в вашем примере), сохраните его как _id, и MongoDB сделает для вас тяжелую работу.

+0

Я обновил сообщение, чтобы лучше отразить мои вопросы. Я бы предпочел, чтобы он создал его для меня. Я использовал MongoMapper в течение некоторого времени, и все было найдено, когда он создает идентификаторы. Однако я вернусь к драйверу, чтобы использовать атомные обновления для встроенных документов, которые MongoMapper не преуспевает, и я смущен тем, почему я не могу просто создать встроенный идентификатор документа. – user577808

+1

Я просто посмотрел ваше обновление - MongoDB добавляет _id только в документ верхнего уровня. Это похоже на нечто странное, что делает MongoMapper (к сожалению, я не знаком с MongoMapper), чтобы отслеживать ссылки между документами для вас. Разве образование хранится как отдельный объект где-то в другом месте? Если это так, то я предполагаю, что _id является тем же самым, что и свойство _id этого образования в другой коллекции. –

+0

Gotcha. Я думал, что все встроенные документы будут иметь идентификатор, чтобы на него можно было ссылаться по URL. Я запрашивал образование с консоли, и он должен просто назначить ему идентификатор на лету, если он его не имеет. Наверное, мне просто нужно пойти с моим последним синтаксисом, чтобы он создавал один, поэтому я могу выполнять обычные операции CRUD для встроенных элементов. Благодаря! – user577808

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