如何在MongoDB中设置子子数组项

时间:2010-08-13 00:33:25

标签: mongodb

我正在开发一个webapp,它有一个portal-ish组件(想想多个面板,可以在列到列之间添加药物并添加或删除)。我正在使用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 个答案:

答案 0 :(得分:14)

如果您知道数组中的索引,则可以使用点表示法直接访问数组元素。

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

确保将引号中的点标记路径包含为字符串。

修改

为了更详细地说明它如何动态工作,我将在PHP中给出一个例子:

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

是的有positional operator,但是does not appear to be advanced enough来更改数组中的数组,这可能会在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给它的唯一ID,因此您可以轻松查询和自动设置选项。

update({'_id': ObjectId('idstring')}, {$set : { 'top' : 125}});

答案 1 :(得分:0)

我也有这样的情况,我在$ pull之后跟着$ addToSet替换,即更新我需要的东西。

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

然后删除旧值

update({_id:ObjectId(....)},{$pull : { columns.$.panels : {"top" : 100} }})