在mongodb中更新嵌套数组

我在MongoDB中有一个需要更新的对象的2级深度嵌套数组,如下所示:

{ id: 1, items: [ { id: 2, blocks: [ { id: 3 txt: 'hello' } ] } ] } 

如果只有一个级别的深度数组,我可以使用位置运算符来更新其中的对象,但对于第二级别,唯一的select是使用位置运算符与嵌套对象的索引,如下所示:

 db.objects.update({'items.id': 2}, {'$set': {'items.$.blocks.0.txt': 'hi'}}) 

这种方法的作品,但我似乎是危险的,因为我build立一个Web服务和索引号应该来自客户端,可以发送100000作为索引,这将迫使MongoDB创build一个具有空值100000索引的数组。

有没有其他的方式来更新这样的嵌套对象,我可以引用对象的ID而不是它的位置,或者可能的方式来检查提供的索引是否越界之前,在查询中使用它?

这里有个大问题,你需要利用Mongo的“addToSet”和“push”操作吗? 如果你真的打算修改数组中的单个项目,那么你应该把这些数组作为对象来构build。

以下是我将如何构build这个:

 { id: 1, items: { "2" : { "blocks" : { "3" : { txt : 'hello' } } }, "5" : { "blocks" : { "1" : { txt : 'foo'}, "2" : { txt : 'bar'} } } } } 

这基本上将所有内容转换为JSON对象而不是数组。 你失去了使用$push$addToSet的能力,但我认为这使得一切都变得容易了。 例如,您的查询将如下所示:

db.objects.update({'items.2': {$exists:true} }, {'$set': {'items.2.blocks.0.txt': 'hi'}})

你也会注意到我已经抛弃了“ID”。 当你嵌套这样的事情时,你通常可以用这个数字作为索引来代替“ID”。 现在暗示了“ID”概念。

您使用的ID是线性数字,它必须来自某个地方,比如“max_idx”或类似的附加字段。 这意味着一个查找id,然后更新。 UUID / ObjectId可用于确保您也可以使用分布式CRUD的ID。