Allan 译 The Little MongoDB Book (Chapter 2 - Updating)

Chapter 2 - Updating
在第一章中我们介绍了四个CRUD(create, read, update和delete)操作中的三个。在这一章中了解我们跳过的个:update。 Update有几个让人惊叹的行为,这也就是为什么我们为什么用一章来介绍它。

Update: Replace Versus $set
在它最简单的形式,update带有两个参数:要使用的选择器(where)和要更新的字段。如果Roooooodles已经设置了重量,我们可以执行:

db.unicorns.update({name: 'Roooooodles'}, {weight:  590})

(如果你在使用你的unicorns并且它并没有任何的原始数据,那么现在就去删除所有的文件并插入第一章中的数据)

如果是在真实的编码中,你可能根据_id来更新记录,但是因为我并不知道MongoDB为你生成了什么_id是什么,所以我们选择使用name。现在,如果我们查看更新的记录:

db.unicorns.find({name: 'Roooooodles'})

你会发现update让你第一个惊讶的地方。因为我们执行的第二个参数将会替换掉原有的数据,所以你不会查找到任何数据。换句话说,update根据name查找到一个文件,并用第二个参数替换掉整个文件。这和SQL的update操作是不同的。在某些情况下,这样做是理想,这可以真正的动态更新提供补充。然而,当我想做的只是想更换一个值,或几个值,你最好使用MongoDB的 $set 修饰符。

db.unicorns.update({weight: 590}, {$set: {name: 'Roooooodles', dob: new Date
(1979, 7, 18, 18, 44), loves: ['apple'], gender: 'm', vampires: 99}})

它将重置所有丢失的字段。因为我们没的指定weight,所以它不会被重写。现在如果我们执行:

db.unicorns.find({name: 'Roooooodles'})

我们会得到希望的结果。因此,正确的更新体重的方式为:

db.unicorns.update({name: 'Roooooodles'}, {$set: {weight: 590}})

Update修饰符
除了$set,我们可以补充另外几个修饰符来做一些性感的东西。所有的这些update修饰符都是工作在字段上,所以你的整个文件不会被清除。例如,$inc修饰符通过包含一个正数或负数来实现字段值的增加。例如,如果Pilot被错误的增加了两个杀死吸血鬼战绩,我们可以通过这样来改正:

db.unicorns.update({name: 'Pilot'}, {$inc: {vampires: -2}})

如果Aurora突然爱吃甜食,我们可以通过$push修饰符来为她的loves字段添加值:

db.unicorns.update{(name: 'Aurora'}, {$push: {loves: 'sugar'}})

MongoDB官网上的Updating章节提供了另外的有用的update修饰符。

Upserts
update中的一个更让人惊喜特性是它完全支持upserts。一个upserts如果发现文件就更新,否则就插入之。Upserts在某些情况下特别灵活,当你使用了一次,你就知道了。把第三个参数设置为true就可支持upserting。

一个最常见的例子就是网站计数器。如果我们想要实时保持一个总数,我们将不得不查看这一页的记录是否已经存在,并且根据它来决定要运行update或insert。省略了第三个参数(或者设置为false),执行下面的命令将不会做任何东西:

db.hits.update({page: 'unicorns'}, {$inc: {hits: 1}});
db.hits.find();

然而,如果我们使用upserts,结果将会完全不同:

db.hits.update({page: 'unicorns'}, {$inc: {hits: 1}}, true);
db.hits.find();

因为没有page等于unicorns,一个新文件会被插入。如果我们第二次执行它,那么已存在的hits将会增加到2。

db.hits.update({page: 'unicorns'}, {$inc: {hits: 1}}, true);
db.hits.find();

Multiple Updates
现在介绍update提供的最后一个惊喜,默认情况下,它会更新单个文件。目前来说,所有我们已经看到的这些例子,还是符合逻辑的。然而,如果我们像下面这样执行命令:

db.unicorns.update({}, {$set: {vaccinated: true }});
db.unicorns.find({vaccinated: true});

如果你希望你的珍贵的独角兽都注射疫苗。要想达到你想要的效果,第四个参数必须设置为true:

db.unicorns.update({}, {$set: {vaccinated: true}}, false, true);
db.unicorns.find({vaccinated: true});

In This Chapter
本章结束了对collection中的基本CURD操作。我们介绍了update中的有意思的三个行为特性。首先,不同于SQL更新,MongoDB的更新会取代实际的文件。正因为此,$set修饰符特别的有用。第二,update支持upsert,这对于成对的$inc
修饰符会很有帮助。最后,默认情况下,update只会更新第一个查找到的文件。

一定要记住我们查看MongoDB是从它的shell窗囗。驱动器和类库通过不同的API可能会修改默认的行为。例如,Ruby驱动器把最后两个参数合并为{:upsert =>false, :multi=>false}。

 

原文:

Chapter 2 - Updating
In chapter 1 we introduced three of the four CRUD (create, read, update and delete) oper-
ations. This chapter is dedicated to the one we skipped over: update. Update has a few
surprising behaviors, which is why we dedicate a chapter to it.
Update: Replace Versus $set
In its simplest form, update takes 2 arguments: the selector (where) to use and what field to
update with. If Roooooodles had gained a bit of weight, we could execute:
db.unicorns.update({name: 'Roooooodles'}, {weight: 590})
(if you've played with your unicorns collection and it doesn't have the original data anymore,
go ahead and remove all documents and re-insert from the code in chapter 1.)
If this was real code, you'd probably update your records by _id, but since I don't know what
_id MongoDB generated for you, we'll stick to names. Now, if we look at the updated record:
db.unicorns.find({name: 'Roooooodles'})
You should discover updates first surprise. No document is found because the second param-
eter we supply is used to replace the original. In other words, the update found a document
by name and replaced the entire document with the new document (the 2nd parameter). This
is different than how SQL's update command works. In some situations, this is ideal and can
be leveraged for some truly dynamic updates. However, when all you want to do is change
the value of one, or a few fields, you are best to use MongoDB's $set modifier:
db.unicorns.update({weight: 590}, {$set: {name: 'Roooooodles', dob: new Date
(1979, 7, 18, 18, 44), loves: ['apple'], gender: 'm', vampires: 99}})
This'll reset the lost fields. It won't overwrite the new weight since we didn't specify it. Now
if we execute:
db.unicorns.find({name: 'Roooooodles'})
We get the expected result. Therefore, the correct way to have updated the weight in the first
place is:
db.unicorns.update({name: 'Roooooodles'}, {$set: {weight: 590}})
Update Modifiers
In addition to $set, we can leverage other modifiers to do some nifty things. All of these
update modifiers work on fields - so your entire document won't be wiped out. For example,
the $inc modifier is used to increment a field by a certain positive or negative amount. For
example, if Pilot was incorrectly awarded a couple vampire kills, we could correct the mistake
by executing:
db.unicorns.update({name: 'Pilot'}, {$inc: {vampires: -2}})
If Aurora suddenly developed a sweet tooth, we could add a value to her loves field via the
$push modifier:
db.unicorns.update({name: 'Aurora'}, {$push: {loves: 'sugar'}})
The Updating section of the MongoDB website has more information on the other available
update modifiers.
Upserts
One of updates more pleasant surprises is that it fully supports upserts. An upsert updates
the document if found or inserts it if not. Upserts are handy to have in certain situations and,
when you run into one, you'll know it. To enable upserting we set a third parameter to true.
A mundane example is a hit counter for a website. If we wanted to keep an aggregate count
in real time, we'd have to see if the record already existed for the page, and based on that
decide to run an update or insert. With the third parameter omitted (or set to false), executing
the following won't do anything:
db.hits.update({page: 'unicorns'}, {$inc: {hits: 1}});
db.hits.find();
However, if we enable upserts, the results are quite different:
db.hits.update({page: 'unicorns'}, {$inc: {hits: 1}}, true);
db.hits.find();
Since no documents exists with a field page equal to unicorns, a new document is inserted.
If we execute it a second time,the existing document is updated and hits is incremented to
2.
db.hits.update({page: 'unicorns'}, {$inc: {hits: 1}}, true);
db.hits.find();
Multiple Updates
The final surprise update has to offer is that, by default, it'll update a single document. So far,
for the examples we've looked at, this might seem logical. However, if you executed something
like:
db.unicorns.update({}, {$set: {vaccinated: true }});
db.unicorns.find({vaccinated: true});
You'd likely expect to find all of your precious unicorns to be vaccinated. To get the behavior
you desire, a fourth parameter must be set to true:
db.unicorns.update({}, {$set: {vaccinated: true }}, false, true);
db.unicorns.find({vaccinated: true});
In This Chapter
This chapter concluded our introduction to the basic CRUD operations available against a col-
lection. We looked at update in detail and observed three interesting behaviors. First, unlike
an SQL update, MongoDB's update replaces the actual document. Because of this the $set
modifier is quite useful. Secondly, update supports an intuitive upsert which is particularly
useful when paired with the $inc modifier. Finally, by default, update only updates the first
found document.
Do remember that we are looking at MongoDB from the point of view of its shell. The driver
and library you use could alter these default behaviors or expose a different API. For example,
the Ruby driver merges the last two parameters into a single hash: {:upsert => false, :
multi => false}.

译者努力翻译,希望转载者注明文章出处及作者。谢谢







转载于:https://www.cnblogs.com/chalgcn/archive/2011/11/08/2241678.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值