原文地址
update:replace VS $ set
update最简单的使用方式,就是使用两个参数。selector 和将要进行更新的 field。如果Rooooooodles 的重量增加了,可以这样做:
db.unicorns.upate({name:'Roooooodles'},{weight:590})
现在,如果你查找更新过的记录:
db.unicorns.find({name:'Roooooodles'})
现在,你将发现一个奇怪的现象,上面这条查找命令什么并没有找到包含有Roooooodles这条记录的document。实际上,我们并没有使用更新操作符,而是直接替换了原有的文档。换而言之,这条update命令通过 name 找到了该条文档,并使用新的文档进行了替换操作。
//原文档
{name: 'Roooooodles',
dob: new Date(1979, 7, 18, 18, 44),
loves: ['apple'],
weight: 575,
gender: 'm',
vampires: 99}
//替换为
{weight:590}
当你希望改变field的时候,你必须使用 $set 操作符。现在重置由上面那条update命令造成丢失的field:
db.unicorns.update(
{weight:590},{
$set:{name:'Roooooodles',dob:new Data(1979,7,18,18,44),loves:['apple'],gender:'m',vampires:99}
}
)
这时,将不会覆盖weight,现在执行:
{db.unicorns.find({name:'Roooooodles'})}
我们将得到一开始期望的结果。即,只是希望weight发生改变。
update操作符
除了 $set 操作符,我们还可以借助一些其他的操作符完成一些漂亮的(nifty)事。所有的更新操作都将基于 field 完成。所以,整个文档并不会被擦除(wiped out)。
举个例子,$inc 操作符被用来增加(increment)一个field,这个增量可以是一个正数或者负数。如果Pilot被错误的增加了2个vampire的击杀,现在我们来纠正这个错误:
db.unicorns.update({name:'Pilot'},{$inc:{vampirs:-2}})
如果Aurora忽然很喜欢吃糖,现在我们通过 $push 在她的 field 中增加进去:
db.unicorns.update({name:'Aurora'},{$push:{loves:'sugar'}})
Upserts
update是支持upsert参数的。这是update的第三个参数,默认为flase,如果设置为true,它会首先通过seletor查找这个document,如果没有找到,则作为新的document插入。
一个比较常见的例子是网站的点击量。如果我们想得到实时的总数(aggregate count),我们需要查找对于某个页面来说总数记录是否已经存在,基于此决定是需要更新还是插入。
db.hits.update({page:'unicorns'},{$inc:{hits:1},{upsert:true}})
更新多个文档
默认情况下,update只会更新一个document。
db.unicorns.update({},{$set:{vaccinated:true}} ;
db.unicorns.find({vaccinated:true})
如果你想更新多个,需要将multi选项设置为true。
db.unicorns.update({},{$set:{vaccinated:true}},{multi:true})