Как $ установить элементы вложенных массивов в MongoDB - PullRequest
8 голосов
/ 13 августа 2010

Я разрабатываю веб-приложение, в котором есть компонент портала (например, несколько панелей, которые можно перемещать из столбца в столбец и добавлять или удалять).Я использую MongoDB для хранения этой информации в таком формате, как ...

{
    _id: ObjectId(...),
    title: 'My Layout',
    columns: [
        {
            order: 1,
            width: 30,
            panels: [
                { title: 'Panel Title', top: 100, content: '...' },
                { title: 'Panel Title', top: 250, content: '...' },
            ]
        },
        {
            ... multiple columns ...
        }
    ]
}

Я пытаюсь использовать атомарные операции / операции модификатора с update () , и это становитсясбивает с толку.Если я хочу просто обновить одно свойство определенной панели, как я могу ссылаться на это?

update(
    { _id: ObjectId(...) },
    { $set: { columns.[???].panels.[???].top: 500 }
)

Ответы [ 2 ]

14 голосов
/ 13 августа 2010

Если вы знаете индекс в массиве, вы можете получить доступ к элементу массива напрямую, используя точечную нотацию.

update(
{ _id: ObjectId(xxxx) },
{ $set: { 'columns.0.panels.0.top' : 125}}
)

Убедитесь, что вы заключили точечный путь в кавычки в строку.

Редактировать:

Чтобы подробнее узнать о том, как это может работать динамически, я приведу пример на PHP:

$action = array("columns.$colNum.panels.$panelNum" => $newValue);

Да, есть позиционный оператор , но он выглядит недостаточно продвинутым для изменения массивов внутри массивов, это может измениться в MongoDB 1.7.0

Есть альтернатива, которую вы можете сделать вместо этогопытаться вложить эту информацию во вложенный документ.Попробуйте сгладить это.Вы можете создать коллекцию, которая имеет объекты панели и столбца:

объект столбца:

{
_id: // MongoId
type: 'column',
user: 'username',
order: 1,
width: 30,
}

объект панели:

{
_id: //MongoId
type: 'panel',
user: 'username',
parentColumn: //the columns _id string
top: 125,
left: 100
}

Затем вы можете найти все принадлежащие столбцыпользователю:

find({ type: 'column', user:'username'});

Вы можете найти все панели для определенного столбца, выполнив:

find({type: 'panel', columnOwner:'ownerID'});

Поскольку каждый столбец и панель будут иметь уникальный идентификатор, данный MongoDB дляэто, вы можете легко запросить и атомарно установить параметры.

update({'_id': ObjectId('idstring')}, {$set : { 'top' : 125}});
0 голосов
/ 07 апреля 2014

У меня тоже была такая ситуация, я следовал $ addToSet после $ pull, чтобы заменить то есть обновить то, что мне было нужно.

 update(
{ _id: ObjectId(...) },
{ $addToSet: { columns.$.panels : "new sub-Doc" }
)

А затем удалите старое значение

update({_id:ObjectId(....)},{$pull : { columns.$.panels : {"top" : 100} }})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...