在 MongoDB 中更新插入
在 MongoDB 中,upsert 是一个用于更新操作的选项,例如 update()、findAndModify() 等。或者换句话说,upsert 是更新和插入的组合(更新 + 插入 = upsert)。如果此选项的值设置为 true 并且找到与指定查询匹配的一个或多个文档,则更新操作将更新匹配的一个或多个文档。或者,如果此选项的值设置为 true 并且没有一个或多个文档与指定的文档匹配,则此选项会在集合中插入一个新文档,并且此新文档具有操作中指示的字段。默认情况下, upsert 选项的值为 false。如果分片集合中 upsert 的值为 true,则您必须在过滤器中包含完整的共享密钥。
句法:
upsert:
upsert 选项的值是 true 或 false。
现在我们将学习 upsert 选项的用法:
使用 findAndModify() 方法进行更新:
我们可以使用带有 findAndModify() 方法的 upsert 选项。在此方法中,此选项的默认值为 false。如果我们将此选项的值设置为 true,则该方法执行以下操作之一:
- 如果找到匹配给定查询条件的一个或多个文档,则 findAndModify() 方法更新文档/文档。
- 如果没有文档/文档与给定的查询条件匹配,则 findAndModify() 方法在集合中插入一个新文档。
句法:
db.Collection_name.findAndModify(
{
selection_criteria:
sort:
remove:
update:
new:
fields:
upsert:
bypassDocumentValidation:
writeConcern:
collation:
arrayFilters: [
})
例如:
在这个例子中,我们正在使用
Database: gfg
Collection: employee
Database: three documents that contains details of employees
现在我们将通过将 upsert 选项的值设置为 true 来在员工集合中插入一个新文档。
db.employee.findAndModify({query:{name:"Ram"},
update:{$set:{department:"Development"}},
upsert:true})
在这里,没有文档与名称“Ram”匹配,因此 findAndModify() 方法插入一个包含两个字段(即名称:“Ram”和部门:“Development”)的新文档,因为 upsert 选项的值设置为真的。
使用 update() 方法进行更新:
我们可以在 update() 方法中使用 upsert 选项。在此方法中,此选项的默认值为 false。如果我们将此选项的值设置为 true,则该方法执行以下操作之一:
- 如果找到与给定查询条件匹配的一个或多个文档,则 update() 方法更新文档/文档。
- 如果没有文档/文档与给定的查询条件匹配,则 update() 方法在集合中插入一个新文档。
注意:为防止 MongoDB 多次插入同一文档,请在 name 字段上创建唯一索引。使用唯一索引,如果多个文档需要使用 upsert: true 进行相同更新,则只有一次更新操作成功插入新文档。
句法:
db.Collection_name.update({Selection_criteria}, {$set:{Update_data}}, {
upsert:
multi:
writeConcern:
collation:
arrayFilters: [
hint:
})
例如:
在这个例子中,我们正在使用
Database: gfg
Collection: employee
Database: three documents that contains details of employees
现在我们将通过将 upsert 选项的值设置为 true 来在员工集合中插入一个新文档。
db.employee.update({name:"Priya"}, {$set: {department: "HR"}},{upsert:true})
在这里,没有文档与名称“Priya”匹配,因此 update() 方法插入一个包含两个字段(即名称:“Priya”和部门:“HR”)的新文档,因为 upsert 选项的值设置为真的。
使用运算符表达式更新插入:
如果没有文档与给定集合中的过滤器匹配,并且更新参数是包含更新运算符的文档,并且 upsert 选项的值也设置为 true,则更新操作会根据给定查询参数中的相等子句创建新文档,并且应用来自更新参数的表达式。或者换句话说,当 upsert 选项的值为 true 并且没有文档匹配给定过滤器时,则更新操作在给定集合中插入一个新文档,这个新文档中插入的字段就是查询中指定的字段并更新文件。
例子:
在这个例子中,我们正在使用
Database: gfg
Collection: example
Database: five documents that contains details of students
现在我们将通过将 upsert 选项的值设置为 true 来在示例集合中插入一个新文档。
db.example.update({Name: "Rekha"}, // Query parameter
{$set: {Phone: '7841235468 '}, // Update document
$setOnInsert: {Gender: 'Female'}},
{upsert: true})
在这里,update() 方法根据查询条件创建一个带有字段“Name: Rekha”的新文档,然后将 $set 和 $setOnInsert 操作应用于该文档。
插入替换文件:
如果没有文档与给定集合中的过滤器匹配,并且更新参数包含替换文档,并且 upsert 文档的值也设置为 true,则更新操作会在集合中插入一个新文档,并且在这个新文档中插入的字段是在替换文档中指定的字段。在这里,如果替换文档包含 _id 字段,那么 MongoDB 不会为新文档创建新的 _id 字段。或者,如果替换文档不包含 _id 字段,那么 MongoDB 会为新文档创建一个新的 _id 字段。
注意:不允许在查询参数和替换文档中指定不同的 _id 字段值。如果你这样做,那么你会得到错误。
例子:
在这个例子中,我们正在使用
Database: gfg
Collection: example
Database: four documents that contains details of students
现在我们将通过将 upsert 选项的值设置为 true 来在示例集合中插入一个新文档。
db.example.update({Name:"Hema"}, // Query parameter
{Name:"Hema", Phone:8332564578}, // Replacement document
{upsert:true})
使用聚合管道进行更新:
聚合管道是一个多阶段管道,因此在每个状态下,将文档作为输入并在下一阶段(id 可用)中将生成的文档作为输入并生成输出,这个过程正在进行直到最后阶段。管道可以有 1 到 n 个 stager
如果没有文档与给定的过滤器匹配并且更新参数包含聚合管道,则 upsert 选项的值也设置为 true 然后更新操作在集合中插入一个新文档。这个新文档是从查询参数中存在的相等子句创建的,然后将管道应用于文档以创建要插入的文档。
例子:
在这个例子中,我们正在使用
Database: gfg
Collection: employee
Database: three documents that contains details of employees
现在我们将通过将 upsert 选项的值设置为 true 来在员工集合中插入一个新文档。
db.employee.update({name:”Ram”}, [{$set: {department: “HR”, age:30}}],{upsert:true})
Upsert 带点 _id 查询:
到目前为止,我们已经研究了 update() 方法可以根据查询修改集合中的数据,如果在 upsert 选项的帮助下找不到任何匹配的文档,则可以将新字段添加到集合中。但是使用带点 _id 查询的 upsert 是一个例外,如果您尝试以这种方式插入文档,MongoDB 将向您显示错误。
例子:
考虑以下更新操作。由于更新操作指定了 upsert:true 并且查询使用点表示法在 _id 字段上指定了条件,因此在构造要插入的文档时更新将导致错误。
db.employee.update({“_id.name”:”Roma”, “_id.uid”:0},{age:20}, {upsert:true})