Upsert功能在更新方法中很棒,但它似乎有一个很大的缺点,我找不到合理的解决方案。
问题是,如果找到的结果与查询条件匹配,我只想更新一个字段,但找不到任何行,我想插入很多字段。
例如,如果 find({name:John,surname:Connor})返回结果,我只想为他设置新的年龄,例如 {age:33} ,但如果没有找到结果,我想插入很多字段,例如 {姓名:John,姓:Connor,年龄:32,角色:指挥官,角色:谨慎,爱好:'杀死终结者'} < /强>
有一种很好的方法可以在一个查询中实现这一点吗?或者唯一的解决方案是直接的,意思是查找,检查找到多少结果,并根据它插入或更新?
编辑:我做了一个补充,解释了能否一步完成这项工作的必要性。有两个步骤(首先查找,然后插入/更新)的解决方案很好,当有一个工作查找和更新/插入,但这将失败,当有1000个工人将尝试这样做 - 结果我可能在数据库中有很多John Connors(当前几个工人没有找到任何结果并且所有人都插入一个新行时),除非我为Name-Surname对做了一个唯一的索引(不知何故)。但我正在寻找不这样做的解决方案。
答案 0 :(得分:4)
您需要匹配足够的条件以使用文档中的确切值选择特定文档,然后发送所有数据,如果不是,则创建文档已经存在。此外,如果文档不存在,您需要指定upsert
选项来创建文档。
update( {name: "John", surname: "Connor" },
{ $set :
{name: "John", surname: "Connor", age: 32, terminated: false}},
{ upsert: true })
确保您了解使用upsert
的性质。查询需要依赖于唯一字段,或者您可能最终得到具有匹配数据的多个文档。
警告为避免多次插入同一文档,请仅使用 upsert:如果查询字段是唯一索引的,则为true
MongoDB不支持根据查询结果有条件地仅更新文档部分的方法。 不会允许:
updateIf(query, updateIfTrue, updateIfFalse, options)
要有选择地更新部分,您需要执行多个步骤或使用$set
更新整个文档。
答案 1 :(得分:1)
您可以通过与完整文档属性匹配来获得所需的功能,除了要更新的属性。示例如下:
在集合中插入唯一的文档:
db.collection.insert({ name: "John", surname: "Connor", age: 32, role: "commander", character: "cautious", hobby: "kill terminators" })
现在
db.collection.find({"name" : "John", "surname" : "Connor", "role" : "commander", "character" : "cautious", "hobby" : "kill terminators" })
返回:
{ "_id" : ObjectId("52fc9a02d342217e6262aa28"), "name" : "John", "surname" : "Connor", "age" : 32, "role" : "commander", "character" : "cautious", "hobby" : "kill terminators" }
更新声明
db.collection.update({"name" : "John", "surname" : "Connor", "role" : "commander", "character" : "cautious", "hobby" : "kill terminators" },{$set:{age:33}}, { upsert: true })
更新现有文档的属性'age':
{ "_id" : ObjectId("52fc9a02d342217e6262aa28"), "name" : "John", "surname" : "Connor", "age" : 33, "role" : "commander", "character" : "cautious", "hobby" : "kill terminators" }
如果您运行完全相同的更新语句更改名称(因此,查找查询将找不到现有文档):
db.collection.update({"name" : "Robot", "surname" : "Connor", "role" : "commander", "character" : "cautious", "hobby" : "kill terminators" },{$set:{age:33}}, { upsert: true })
“Robot Connor”文档将在33岁时创建,您最终会收集两个文档:
db.collection.find()
{ "_id" : ObjectId("52fc9a02d342217e6262aa28"), "name" : "John", "surname" : "Connor", "age" : 33, "role" : "commander", "character" : "cautious", "hobby" : "kill terminators" }
{ "_id" : ObjectId("52fc9a5f56641f5e1b883677"), "age" : 33, "character" : "cautious", "hobby" : "kill terminators", "name" : "Robot", "role" : "commander", "surname" : "Connor" }
注意:我不相信更新查询参数的额外属性会对性能产生影响。