MongoDB原子操作
在上面的文档中,我们将购买产品的客户的信息嵌入到 product_bought_by 字段中。当有新客户购买该产品时,我们首先会使用 product_available 字段检查该产品是否仍然可用。如果可用,我们就减少 product_available 字段的值,并在 product_bought_by 字段中插入新客户的信息。> db.productDetails.insert(
... {
... "product_name": "Samsung S3",
... "category": "mobiles",
... "product_total": 5,
... "product_available": 3,
... "product_bought_by": [
... {
... "customer": "john",
... "date": "7-Jan-2014"
... },
... {
... "customer": "mark",
... "date": "8-Jan-2014"
... }
... ]
... }
... )
WriteResult({ "nInserted" : 1 })
我们可以使用 findAndModify 令来实现上述功能,如下所示:
上面的示例中我们使用 findAndModify 来查询并更新文档,这样可以确保只有在产品可用时才更新产品购买信息。而且整个过程都在同一个查询中完成。> db.productDetails.findAndModify({query:{_id:ObjectId("603f31435e514debed504a38"), product_available:{$gt:0}}, update:{$inc:{product_available:-1}, $push:{product_bought_by:{customer:"rob", date:"9-Jan-2014"}}}})
{
"_id" : ObjectId("603f31435e514debed504a38"),
"product_name" : "Samsung S3",
"category" : "mobiles",
"product_total" : 5,
"product_available" : 3,
"product_bought_by" : [
{
"customer" : "john",
"date" : "7-Jan-2014"
},
{
"customer" : "mark",
"date" : "8-Jan-2014"
}
]
}
与此相反,假如我们将产品的可用性信息与购买记录分开保存,那么在上面的示例中我们需要先使用一个查询来检查产品是否可用,然后再通过另一个查询来更新购买信息。但是,在执行这两个查询的过程中,可能有其他的用户购买了该产品,导致该产品不可用。在不知道这一点的情况下,我们的第二个查询将根据个查询的结果更新购买信息,这就会导致两个文档中的数据不一致。
常用的原子操作令
$set
用来指定一个键并更新键值,若键不存在则创建。{ $set : { field : value } }
$unset
用来删除一个键。{ $unset : { field : 1} }
$inc
用来对文档的某个数值类型的键值进行增减操作。{ $inc : { field : value } }
$push
用来向文档中追加一些信息。{ $push : { field : value } }
把 value 追加到 field 里面去,field 一定要是数组类型才行,如果 field 不存在,则会新增一个数组类型加进去。$pushAll
与 $push 类似,它可以一次追加多个值到一个数组类型的字段内。{ $pushAll : { field : value_array } }
$pull
从数组 field 内删除一个等于 value 的值。{ $pull : { field : _value } }
$pop
删除数组的个或一个元素。{ $pop : { field : 1 } }
$rename
修改字段的名称。{ $rename : { old_field_name : new_field_name } }
$bit
位操作,integer 类型。{$bit : { field : {and : 5}}}
偏移操作符
> t.find() { "_id" : ObjectId("4b97e62bf1d8c7152c9ccb74"), "title" : "ABC", "comments" : [ { "by" : "joe", "votes" : 3 }, { "by" : "jane", "votes" : 7 } ] }
> t.update( {'comments.by':'joe'}, {$inc:{'comments.$.votes':1}}, false, true )
> t.find() { "_id" : ObjectId("4b97e62bf1d8c7152c9ccb74"), "title" : "ABC", "comments" : [ { "by" : "joe", "votes" : 4 }, { "by" : "jane", "votes" : 7 } ] }
- 随机文章
- 核心危机(核心危机魔石合成攻略)
- 风儿(风儿轻轻的吹)
- 饿了么红包怎么用(饿了么红包怎么用微信支付)
- 儿童教育文章(儿童教育)
- 广州4a广告公司(广州4a广告公司创意总监年薪)
- 抖音卡(抖音卡顿怎么解决)
- xboxones(xboxone手柄怎么配对主机)
- 兵马俑(兵马俑介绍和历史背景)
- 陈武简历
- 帆船比赛(帆船比赛视频)
- 海猫鸣泣之时游戏(海猫鸣泣之时游戏在哪玩)
- 韩国媳妇和小雪(韩国媳妇和小雪的父亲工资是多少)
- 儋州市第二中学(儋州市第二中学录取分数线)
- 鬼泣5攻略(鬼泣5攻略第三关怎么跳)
- 地球日主题(2020年世界地球日主题)
- 和柳亚子(和柳亚子先生于田)
- yy魔兽(yy魔兽世界)
- 充值卡代理(充值卡代理加盟)
- 拆奶罩
- 郭妮小说(恶魔的法则郭妮小说)
- 东天目山(东天目山景区)
- 杭同(杭同培训中心怎么样)
- 蝙蝠给人类的一封信(蝙蝠给人类的一封信)
- 大松电饭煲(美的大松电饭煲)
- 服饰加盟(服饰加盟店招商)
- 疯狂填字(疯狂填字5)
- 点对点短信息(点对点短信息费是什么意思)
- 河北省大运会(河北省大运会时间)
- 哈利波特官网(哈利波特官网在哪里)
- 骇客神条(骇客神条怎么辨别真假)
