2013-04-14 4 views
16

У меня есть схема документа в MongoDB, который выглядит следующим образом:Обновление несколько Вложенного массива в MongoDB

{ 
    _id: 1 
    tags: [{ 
     tag: 'foo' 
     links: [{ 
      link: 'http:www.google.com' 
      date: '123' 
     }] 
    }] 
} 

Я пытаюсь нажать ссылку в массив «ссылка», который будет уникальным для документа.

Мой первый запрос ...

db.userlinks.update (
    {_id: 1, tags: {$nin: [{tag:'foo'}]}}, 
    {$push: {'tags': {tag:'foo'}}}, 
    {upsert: true} 
) 

дает мне это (создает тег, если он не существует)

{ "_id" : 1, "tags" : [ { "tag" : "foo" } ] } 

Я тогда следует, что с этим запросом ...

db.userlinks.update (
    {_id: 1, tags: {tag: 'foo', links: {$nin: [{link: 'http://www.google.com'}]}}}, 
    {$push: {tags: {tag: 'foo', links: {link: 'http://www.google.com', date: '123'}}}}, 
    {upsert: true} 
) 

Но я получаю эту ошибку: «Невозможно применить $ пуш/модификатор $ pushAll, не включенным в массив»

Я уверен, что проблема заключается в компоненте «обновления» моего второго запроса, но я не уверен, как его исправить. Любая помощь будет оценена по достоинству.

EDIT

Мой первый запрос теперь ... (спасибо Джо)

db.userlinks.update (
    {_id: 1, tags: {$nin: [{tag:'foo'}]}}, 
    {$push: {'tags': {tag:'foo', links:[]}}}, 
    {upsert: true} 
) 

Мой второй запрос теперь ...

db.userlinks.update (
    {_id: 1, 'tags.tag': 'foo'}, 
    {$push: {'tags.$.links': {link: 'http://www.google.com', date: '123'} } } 
) 

успешно проталкивает ссылку в массив 'links', однако он также позволяет дублировать. Я не могу разрешить дублирование ссылок. $ addToSet, но если дата изменяется, то она по-прежнему вставляет дублируемую ссылку.

Есть ли способ проверить наличие ссылки в разделе «запрос» моего второго запроса или вместо этого только addToSet, если определенные поля совпадают?

+0

вы не можете. рассмотреть возможность изменения вашей схемы? –

+3

Я не особо хочу изменить свою схему, потому что она смоделирована именно так, как она выводится, что означает, что мне не нужно делать какие-либо перетаскивания данных, как только я выберу это из db. Я думал, что это была основная причина для использования Мондума. Возможность моделирования ваших объектов непосредственно в базу данных и из нее. – 2013-04-15 03:48:50

ответ

18

Я, наконец, получил его ... хотя, если кто-то может увидеть лучший способ сделать это, добавьте его в качестве ответа.

// create the userlinks collection if it doesn't exist 
// also add a tag 'foo' into it, but only if the tag doesn't exist 
db.userlinks.update (
    {_id: '1', 'tags.tag': {$nin: ['foo']}}, 
    {$push: {'tags': {tag:'foo', links:[]}}}, 
    {upsert: true} 
) 

// add a link into the 'foo' tag, but only if the link doesn't exist 
db.userlinks.update(
    {_id: '1', 'tags.tag': 'foo', 'tags.links.link': {$nin: ['http://foobar.com']}}, 
    {$push: {'tags.$.links': {link: 'http://foobar.com', date: '15'} } } 
) 
+1

Интересно. Спасибо за обновление. Не стесняйтесь отмечать свой ответ, как принято. –

+0

@Harley: Как мы можем обновить дату до 20, если мы знаем _id, 'tags.tags' и 'tags.links.link' ... db.doc.update ({_ id:, 'tags.tags:,' tags.links.link ':}, {$ inc: {' tags.links. $. date ': 20}}) не работает, поскольку у нас есть два массива. Пожалуйста, помогите –

+0

Извините, Praveen, я не работал с Mongo, так как я сделал этот пост, и я в основном забыл тонкости языка запросов, которых я боюсь. Может быть, открыть новый вопрос? – 2014-02-05 22:37:04

1

Возможно изменить свой первый запрос:

db.userlinks.update (
    {_id: 1, tags: {$nin: [{tag:'foo'}]}}, 
    {$push: {'tags': {tag:'foo', links:[]}}}, 
    {upsert: true} 
) 

$ нажимной операции должны влиять только ссылки, а не тега.

{$push: {'tags.links': {link: 'http://www.google.com', date: '123'} } }, 
+0

Это инициировало «ссылки» на пустой массив, что хорошо и, вероятно, что-то мне нужно, однако мой второй запрос по-прежнему вызывает ту же ошибку. – 2013-04-14 19:35:09

+0

Обновлен ответ. –

+0

К сожалению, у меня все еще есть такая же ошибка, используя это как второй запрос: db.userlinks.update ( {_id: 1, tags: {tag: 'foo', links: {$ nin: [{link: 'google. com '}]}}}, {$ push: {' tags.links ': {link:' google.com ', date:' 123 '}}}, {upsert: true} ) – 2013-04-14 19:59:15

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