MongoDB:upsert子文档

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

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

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

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

.我想更新{ 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:upsert子文档

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

发布评论

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

>www.elefans.com

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