gpt4 book ai didi

mongodb - 在 MongoDB 中更新文档时的条件更新插入(插入)

转载 作者:可可西里 更新时间:2023-11-01 10:40:59 26 4
gpt4 key购买 nike

我在 MongoDB 中有一些文档,看起来像这样:

{type: type1, version: 2, data: ...}
{type: type1, version: 3, data: ...}
{type: type2, version: 1, data: ...}
{type: type2, version: 2, data: ...}
...

我想更新匹配类型版本的数据,或者当版本 不匹配但想禁止使用新类型 创建新文档当我这样做时:

db.getCollection('products').update({"type": "unknown_type", "version" : "99"}, {$set: {"version": 99, "data": new data}}, {"upsert": true})

它创建一个新文档:

{type: unknown_type, version: 99, data: ...}

这正是我想禁止的。有没有办法在一个电话中完成这个操作?有没有办法限制某些字段的值?

最佳答案

对于这个用例,我能看到的最佳处理方式是使用 "Bulk Operations"为了在同一请求中发送“更新”和“插入”命令。我们还需要在此处有一个唯一索引,以强制您实际上不会创建这两个字段的新组合。

从这些文档开始:

{ "type" : "type1", "version" : 2 }
{ "type" : "type1", "version" : 3 }
{ "type" : "type2", "version" : 1 }
{ "type" : "type2", "version" : 2 }

并在这两个字段上创建唯一索引:

db.products.createIndex({ "type": 1, "version": 1 },{ "unique": true })

然后我们尝试做一些实际插入的事情,对更新和插入都使用批量操作:

db.products.bulkWrite(
[
{ "updateOne": {
"filter": { "type": "type3", "version": 1 },
"update": { "$set": { "data": {} } }
}},
{ "insertOne": {
"document": { "type": "type3", "version": 1, "data": { } }
}}
],
{ "ordered": false }
)

我们应该得到这样的响应:

{
"acknowledged" : true,
"deletedCount" : 0,
"insertedCount" : 1,
"matchedCount" : 0,
"upsertedCount" : 0,
"insertedIds" : {
"1" : ObjectId("594257b6fc2a40e470719470")
},
"upsertedIds" : {

}
}

注意这里的 matchedCount0 反射(reflect)了“更新”操作:

        "matchedCount" : 0,

如果我用不同的数据再次做同样的事情:

db.products.bulkWrite(
[
{ "updateOne": {
"filter": { "type": "type3", "version": 1 },
"update": { "$set": { "data": { "a": 1 } } }
}},
{ "insertOne": {
"document": { "type": "type3", "version": 1, "data": { "a": 1 } }
}}
],
{ "ordered": false }
)

然后我们看到:

BulkWriteError({
"writeErrors" : [
{
"index" : 1,
"code" : 11000,
"errmsg" : "E11000 duplicate key error collection: test.products index: type_1_version_1 dup key: { : \"type3\", : 1.0 }",
"op" : {
"_id" : ObjectId("5942583bfc2a40e470719471"),
"type" : "type3",
"version" : 1,
"data" : {
"a" : 1
}
}
}
],
"writeConcernErrors" : [ ],
"nInserted" : 0,
"nUpserted" : 0,
"nMatched" : 1,
"nModified" : 1,
"nRemoved" : 0,
"upserted" : [ ]
})

这将在所有驱动程序中持续抛出错误,但我们也可以在响应的详细信息中看到:

        "nMatched" : 1,
"nModified" : 1,

这意味着即使“插入”失败了,“更新”实际上也完成了它的工作。这里要注意的重要一点是,虽然“错误”可能发生在“批处理”中,但我们可以在它们属于预测类型时处理它们,这是我们预测的重复键错误的 11000 代码预期。

所以最终数据当然是这样的:

{ "type" : "type1", "version" : 2 }
{ "type" : "type1", "version" : 3 }
{ "type" : "type2", "version" : 1 }
{ "type" : "type2", "version" : 2 }
{ "type" : "type3", "version" : 1, "data" : { "a" : 1 } }

这就是您想在这里实现的目标。

因此操作将产生异常,但是通过使用 .bulkWrite(){ "ordered": false } 选项标记为“无序”然后它至少会提交任何没有导致错误的指令。

在这种情况下,典型的结果是要么“插入”有效但没有更新,要么“插入”在应用“更新”的地方失败。当响应中返回失败时,您可以检查错误的“索引”是 1 表示预期的“插入”失败并且错误代码是 11000 因为预期的“重复键”。

因此可以忽略“预期”情况下的错误,您只需处理不同代码和/或发出的批量指令中不同位置的“意外”错误。

关于mongodb - 在 MongoDB 中更新文档时的条件更新插入(插入),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44562228/

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