Обновление многоядерного массива в 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}
)

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

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

РЕДАКТИРОВАТЬ

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

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, если определенные поля совпадают?

Ответ 1

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

// 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'} } }
)

Ответ 2

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

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

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

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