如何在mongodb中更新子文档

4

我知道这个问题已经被问了很多次,但我不知道如何在Mongo中更新子文档。

这是我的模式:

// Schemas
var ContactSchema = new mongoose.Schema({
  first: String,
  last: String,
  mobile: String,
  home: String,
  office: String,
  email: String,
  company: String,
  description: String,
  keywords: []
});

var UserSchema = new mongoose.Schema({
  email: {
      type: String,
      unique: true,
      required: true
  },
  password: {
      type: String,
      required: true
  },
  contacts: [ContactSchema]
});

我的收藏夹看起来像这样:

db.users.find({}).pretty()
{
    "_id" : ObjectId("5500b5b8908520754a8c2420"),
    "email" : "test@random.org",
    "password" :     "$2a$08$iqSTgtW27TLeBSUkqIV1SeyMyXlnbj/qavRWhIKn3O2qfHOybN9uu",
    "__v" : 8,
    "contacts" : [
        {
            "first" : "Jessica",
            "last" : "Vento",
            "_id" : ObjectId("550199b1fe544adf50bc291d"),
            "keywords" : [ ]
        },
        {
            "first" : "Tintin",
            "last" : "Milou",
            "_id" : ObjectId("550199c6fe544adf50bc291e"),
            "keywords" : [ ]
        }
    ]
}

假设我想通过以下方式更新id为550199c6fe544adf50bc291e的子文档:

db.users.update({_id: ObjectId("5500b5b8908520754a8c2420"), "contacts._id": ObjectId("550199c6fe544adf50bc291e")}, myNewDocument)

使用 myNewDocument 的方式如下:

{ "_id" : ObjectId("550199b1fe544adf50bc291d"), "first" : "test" }

它返回一个错误:
db.users.update({_id: ObjectId("5500b5b8908520754a8c2420"), "contacts._id":     ObjectId("550199c6fe544adf50bc291e")}, myNewdocument)
WriteResult({
    "nMatched" : 0,
    "nUpserted" : 0,
    "nModified" : 0,
    "writeError" : {
        "code" : 16837,
        "errmsg" : "The _id field cannot be changed from {_id:     ObjectId('5500b5b8908520754a8c2420')} to {_id:     ObjectId('550199b1fe544adf50bc291d')}."
    }
})

我知道MongoDB试图替换父文档而不是子文档,但最终我不知道如何更新我的子文档。

1个回答

11
你需要使用$ operator来更新数组中的子文档。
使用contacts.$将指向mongoDB以更新相关的子文档。
db.users.update({_id: ObjectId("5500b5b8908520754a8c2420"), 
  "contacts._id": ObjectId("550199c6fe544adf50bc291e")}, 
 {"$set":{"contacts.$":myNewDocument}})

我不确定你为什么要更改子文档的_id。这是不可取的。
如果您想更改子文档的特定字段,请使用contacts.$.<field_name>来更新子文档的特定字段。

不幸的是,它会触发一个错误:“2015-03-12T16:36:05.188+0100不能在字段名称中使用'.'[contacts.$.]",位于src/mongo/shell/collection.js:155。 - Buzut
1
@user1717735 抱歉,我忘记了$set运算符。请检查编辑。 - ma08
它有效了,非常感谢!我没有改变_id,它是一样的。实际上,我使用mongoose编程命令。我不知道哪些字段会更改,因此无法具体说明contacts.$.<field_name> - Buzut
我刚意识到在对象中不必再次指定_id,我误解了这一点,这就是你认为我试图更改_id的原因。 - Buzut
这个解决方案是否用新值替换整个子文档?我试图使用用户发送的对象更新一个或两个字段值。但它正在用一个新文档替换子文档。 - Jay

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