在MongoDB中替换数组中嵌入的文档

17

有没有一种简单的方法可以替换数组中嵌入文档的整个内容呢?比如要替换:

{
   "_id" : "2",
      "name" : "name2",
      "xyz..." : "xyz2..."
}

使用:

{
   "_id" : "2",
      "name" : "name6",
      "xyz..." : "xyz5..."
      "morefields..." : "fields..."
}

如何搜索嵌套的 _id?或者我需要使用 $set 逐个替换每个字段吗?

{
  "_id" : "2",
  "users" : [{
      "_id" : "1",
      "name" : "name1",
      "xyz..." : "xyz1..."
    }, {
      "_id" : "2",
      "name" : "name2",
      "xyz..." : "xyz2..."
    }],
  "name" : "main name"
}
1个回答

26

你正在使用“对象数组”模式。您可以使用位置操作符,它应该类似于以下内容:

coll.update( {'_id':'2', 'users._id':'2'}, {$set:{'users.$':{ "_id":2,"name":"name6",... }}}, false, true)

根据我的经验,如果对象具有自然 ID,则“对象数组”模式并不是最优选择。在您的情况下,可以建模为以下内容:

{
  "_id" : "2",
  "users" : 
    { "1" : { "name" : "name1", "xyz..." : "xyz1..." }, 
      "2" : { "name" : "name2", "xyz..." : "xyz2..." }
    }
  "name" : "main name"
}
在这种情况下,你可以使用点表示法轻松更新所需的项目。
var newValue = {  "name" : "name6", "xyz..." : "xyz5...", "morefields..." : "fields..." };
coll.update({_id: 2}, { $set: { "users.2" : newValue } });

非常好,谢谢!第二种方法很有趣,但我不确定它是否可行,因为我需要删除一些中间的条目。我假设“users.2”是数组中的位置。 - Fredrik L
我以为users.2是指数组位置,但实际上它使用的是id(并且对于所有其他数组项返回空括号),很酷。 - Fredrik L
MongoDB 在查询中能够识别数组。所以 users.2 可以搜索 users 数组中带有 key2 的对象,或者 它也可以查找 users 中的 key:2 - Gates VP
2
我一开始是倾向于使用你的第二个模型,但现在我认为我无法对内部的名称字段进行索引。如果它是一个数组,那么它应该是users.name,但这里是users.1.name和users.2.name? - Fredrik L
3
你说得对,第二个结构在索引方面并不是很好。这绝对是一个权衡。但你不能为了所有的 MongoDB 查询进行优化。如果你想让这个查询变快,那么你就必须牺牲更新的便利性。 - Gates VP
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接