MongoDB:更新插入子文档

编程入门 行业动态 更新时间:2024-10-17 17:20:00
本文介绍了MongoDB:更新插入子文档的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我有看起来像这样的文档,在 bars.name 上有一个唯一索引:

I have documents that looks something like that, with a unique index on bars.name:

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

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

. I want to either update the sub-document where { name: 'foo', 'bars.name': 'qux' } and $set: { 'bars.$.somefield': 2 }, or create a new sub-document with { name: 'qux', somefield: 2 } under { name: 'foo' }.

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

Is it possible to do this using a single query with upsert, or will I have to issue two separate ones?

相关:嵌入文档中的'upsert'(建议更改架构将子文档标识符作为键,但这是两年前的,我想知道现在是否有更好的解决方案.)

Related: 'upsert' in an embedded document (suggests to change the schema to have the sub-document identifier as the key, but this is from two years ago and I'm wondering if there are better solutions now.)

推荐答案

不,确实没有更好的解决方案,所以也许可以解释一下.

No there isn't really a better solution to this, so perhaps with an explanation.

假设您有一个文档,其结构如您所示:

Suppose you have a document in place that has the structure as you show:

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

如果你做这样的更新

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

然后一切正常,因为找到了匹配的文档.但是如果你改变bars.name"的值:

Then all is fine because matching document was found. But if you change the value of "bars.name":

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

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

Then you will get a failure. The only thing that has really changed here is that in MongoDB 2.6 and above the error is a little more succinct:

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" } })

这在某些方面更好,但无论如何你真的不想更新".您要做的是将元素添加到当前不存在名称"的数组中.

That is better in some ways, but you really do not want to "upsert" anyway. What you want to do is add the element to the array where the "name" does not currently exist.

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

So what you really want is the "result" from the update attempt without the "upsert" flag to see if any documents were affected:

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

屈服响应:

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

因此,当修改后的文档为 0 时,您就知道要发布以下更新:

So when the modified documents are 0 then you know you want to issue the following update:

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

确实没有其他方法可以完全按照您的意愿行事.由于对数组的添加不是严格意义上的设置"类型的操作,因此您不能将 $addToSet 与 "批量更新" 功能,以便您可以级联"更新请求.

There really is no other way to do exactly what you want. As the additions to the array are not strictly a "set" type of operation, you cannot use $addToSet combined with the "bulk update" functionality there, so that you can "cascade" your update requests.

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

In this case it seems like you need to check the result, or otherwise accept reading the whole document and checking whether to update or insert a new array element in code.

更多推荐

MongoDB:更新插入子文档

本文发布于:2023-11-22 13:40:24,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1617640.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:文档   MongoDB

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!