2015-05-06 4 views
1

Имеет ли смысл, что у меня есть запись mongodb, одна из ее полей представляет собой массив из двух идентичных встроенных документов (даже «_id» идентичен).mongoid create 2 встроенный документ с тем же mongo «_id»

Я сталкиваюсь с этой проблемой, когда я использую мангоид для создания записей. Я не знаю много о внедрении встроенных документов mongoid, но я думаю, что если эти встроенные документы являются «документами», ни один из них не должен иметь «_id», который уже используется другим документом.

Пример того, что я получил:

{ 
    _id: "123", 
    name: "sylvain", 
    friends: [ ] 
}, 
{ 
    _id: "245", 
    name: "sonia", 
    friends: [ { 
     _id: 123, 
     name: "sylvain" 
    }, 
    { 
     _id: 123, 
     name: "sylvain" 
    } ] 
}, 
{ 
    _id: "456", 
    name: "bob", 
    friends: [ { 
     _id: 123, 
     name: "sylvain" 
    } ] 
} 
+0

Да, _id должен быть уникальным – apneadiving

+0

@apneadiving, что вы подразумеваете под «должен быть уникальным»? Дублирующая ситуация с идентификаторами может иметь смысл или не должна произойти? – benams

+0

Я думаю, что это не имеет смысла – apneadiving

ответ

3

Для того, чтобы сделать вещи ясно:

  • Поле _idявляется обязательным на каждом корневой документ коллекции. Он используется для уникально идентифицирует ваш документ. Подумайте об этом как о первичном ключе в своей коллекции. Существует всегда индекс на этом _id поле.
  • Обычно, нет уникального идентификатора для встроенных документов (они просто не нуждаются в том, что: встроенные документах действительно часть своего родительского документа - это не вид на два «присоединились к» коллекции).
  • Но, вы можете добавить поле id во встроенные документы, например, в качестве внешнего ключа. Даже если это может быть довольно запутанным, вы можете даже назвать это _id, если хотите. Однако в этом контексте он не будет иметь особого значения.

Поскольку базы данных NoSQL имеют тенденцию использовать денормализованную схему, в MongoDB довольно распространено использование одинаковых документов в разных корневых документах. Фактически, это один из способов представления отношений «многие ко многим».


Вот вполне допустим пример (даже если, как я уже говорил ранее, использование _id как имя поля может быть запутанным на первый взгляд):

{ 
    _id: "123", 
    name: "sylvain", 
    friends: [ ] 
}, 
{ 
    _id: "245", 
    name: "sonia", 
    friends: [ { 
     _id: 123, 
     name: "sylvain" 
    } ] 
}, 
{ 
    _id: "456", 
    name: "bob", 
    friends: [ { 
     _id: 123, 
     name: "sylvain" 
    } ] 
} 


Как о наличии идентичные документы, встроенные в то же родительский документ: это может быть способ «подсчитать» число ber ссылок от родителя к ребенку. Подумайте о соотношении родительский-дочерний документ в виде графика. Возможно, у вас может быть две ссылки с одного узла на другой. С другой стороны, можно было бы подумать о добавлении некоторого поля «веса» во встроенный документ (так, чтобы присвоить ссылку ). В зависимости от вашего варианта использования оба решения могут иметь плюсы и минусы.

Вот пример с использованием двух различных моделей, представляющих следующие факты:

«Клиент Сильвен в настоящее время занимают два купоны на бесплатную MP3 скачать на нашем магазине»

// customer 
{ 
    _id: "123", 
    name: "sylvain", 
    coupons: [ { 
     _id: 9905, 
     desc: "Free MP3 download" 
    }, 
    { 
     _id: 9905, 
     desc: "Free MP3 download" 
    } ] 
} 

В качестве альтернативы, можно подумать об этом больше:

// customer 
{ 
    _id: "123", 
    name: "sylvain", 
    coupons: [ { 
     _id: 9905, 
     desc: "Free MP3 download", 
     qty: 2 
    } ] 
} 

Как и я, я думаю, что это не так очевидно, если последний действительно лучше прежнего. Например, в последнем случае, когда клиент использует купон, вам нужно будет decrease the qty -- and remove the coupon if qty == 0. Кажется, это больше, чем в первом случае. Но YMMV.

+0

Привет, Вы описали не мое дело. Я прикрепил к моему вопросу пример того, что у меня есть в моей базе данных. – benams

+0

@benams Thnak вы за то, что разъяснили это. Я добавлю пару абзацев к моему ответу об этом. –

+1

С Mongoid встроенными документами являются «Mongoid :: Document's как корневые документы. Таким образом, встроенные документы получают '_id' так же, как и любой другой документ, потому что, ну, ODM тоже хочет их, а '_id 'делают иллюзию« реальных »отношений лучше (т.е. вы можете сказать« o.embeddeds.find (id) 'так же, как вы скажете' o.relateds.find (id) 'в реляционной системе). Разумеется, вы можете вручную работать с массивами хешей, а не с обложенными монголовыми вложенными документами, если вы этого желаете. –

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