gpt4 book ai didi

MongoDB:插入子文档

转载 作者:IT老高 更新时间:2023-10-28 11:05:52 25 4
gpt4 key购买 nike

我有类似的文档,在 bars.name 上有一个唯一索引:

{ name: 'foo', bars: [ { name: 'qux', somefield: 1 } ] }

。我想更新 { name: 'foo', 'bars.name': 'qux' }$set: { 'bars.$.somefield': 2 },或者在 { name: 'foo' } 下使用 { name: 'qux', somefield: 2 } 创建一个新的子文档。

是否可以使用带有 upsert 的单个查询来执行此操作,还是我必须发出两个单独的查询?

相关:'upsert' in an embedded document (建议更改架构以将子文档标识符作为键,但这是从两年前开始的,我想知道现在是否有更好的解决方案。)

最佳答案

不,没有更好的解决方案,所以也许有一个解释。

假设您有一个文件,其结构如您所见:

{ 
"name": "foo",
"bars": [{
"name": "qux",
"somefield": 1
}]
}

如果你进行这样的更新

db.foo.update(
{ "name": "foo", "bars.name": "qux" },
{ "$set": { "bars.$.somefield": 2 } },
{ "upsert": true }
)

然后一切都很好,因为找到了匹配的文档。但是如果你改变“bars.name”的值:

db.foo.update(
{ "name": "foo", "bars.name": "xyz" },
{ "$set": { "bars.$.somefield": 2 } },
{ "upsert": true }
)

那么你就会失败。这里唯一真正改变的是,在 MongoDB 2.6 及更高版本中,错误更加简洁:

WriteResult({
"nMatched" : 0,
"nUpserted" : 0,
"nModified" : 0,
"writeError" : {
"code" : 16836,
"errmsg" : "The positional operator did not find the match needed from the query. Unexpanded update: bars.$.somefield"
}
})

这在某些方面更好,但你真的不想“升级”。您要做的是将元素添加到当前不存在“名称”的数组中。

因此,您真正想要的是没有“upsert”标志的更新尝试的“结果”,以查看是否有任何文档受到影响:

db.foo.update(
{ "name": "foo", "bars.name": "xyz" },
{ "$set": { "bars.$.somefield": 2 } }
)

做出回应:

WriteResult({ "nMatched" : 0, "nUpserted" : 0, "nModified" : 0 })

所以当修改后的文档为 0 时,你就知道要发出以下更新:

db.foo.update(
{ "name": "foo" },
{ "$push": { "bars": {
"name": "xyz",
"somefield": 2
}}
)

确实没有其他方法可以完全按照您的意愿行事。由于对数组的添加并不是严格意义上的“集合”类型的操作,因此您不能将 $addToSet"bulk update" 结合使用那里的功能,以便您可以“级联”您的更新请求。

在这种情况下,您似乎需要检查结果,或者接受阅读整个文档并检查是否在代码中更新或插入新数组元素。

关于MongoDB:插入子文档,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23470658/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com