更新一个字段或插入许多字段(如果不存在)

时间:2014-02-13 09:15:37

标签: mongodb

Upsert功能在更新方法中很棒,但它似乎有一个很大的缺点,我找不到合理的解决方案。

问题是,如果找到的结果与查询条件匹配,我只想更新一个字段,但找不到任何行,我想插入很多字段。

例如,如果 find({name:John,surname:Connor})返回结果,我只想为他设置新的年龄,例如 {age:33} ,但如果没有找到结果,我想插入很多字段,例如 {姓名:John,姓:Connor,年龄:32,角色:指挥官,角色:谨慎,爱好:'杀死终结者'} < /强>

有一种很好的方法可以在一个查询中实现这一点吗?或者唯一的解决方案是直接的,意思是查找,检查找到多少结果,并根据它插入或更新?

编辑:我做了一个补充,解释了能否一步完成这项工作的必要性。有两个步骤(首先查找,然后插入/更新)的解决方案很好,当有一个工作查找和更新/插入,但这将失败,当有1000个工人将尝试这样做 - 结果我可能在数据库中有很多John Connors(当前几个工人没有找到任何结果并且所有人都插入一个新行时),除非我为Name-Surname对做了一个唯一的索引(不知何故)。但我正在寻找不这样做的解决方案。

2 个答案:

答案 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" }

注意:我不相信更新查询参数的额外属性会对性能产生影响。