findAndModify函数的使用

来源:互联网 发布:幼儿网络教育所处行业 编辑:程序博客网 时间:2024/06/11 14:50
findAndModify函数的介绍
findAndModify执行分为find和update两步,属于get-and-set式的操作,它的功能强大之处在于可以保证操作的原子性。
findAndModify对于操作查询以及执行其它需要取值和赋值风格的原子性操作是十分方便的,使用它可以实现一些简单的类事务操作。

findAndModify函数的使用
findAndModify函数有七个参数,每个参数含义如下表所示:
名称作用名称作用
query:<document>
查询文档,用来指明要更新的条件
new:<boolean>
返回更新前的文档还是更新后的文档
sort:<document>
对查询结果排序,默认采用升序
fields:<document>
投影,设置返回文档需要显示的字段
remove:<boolean>
布尔类型,表示是否删除文档
update:<document>
对满足query条件的文档进行更新
upsert:<boolean>
与update函数的upsert参数含义相同
  
findAndModify与update函数的比较:
  • 默认情况下,两个操作都只能修改一个文档(update:{multi:true})
  • 都以原子的方式来更新修改文档
  • 当多个文档满足query条件时:
    • findAndModify使用sort选项,对结果排序,选择第一个文档
    • update不能选择具体更新哪一个文档
  • 返回值不同findAndModify是具体文档update是WriteResult对象
  • findAndModify无法指定writeConcern函数
findAndMofify函数使用实例
var db = connect('localhost:27017/test');
db.findAndModify.drop();
 
// 测试数据
var doc1 = {
_id : 1,
name : 'morris',
age : 19
};
db.findAndModify.insert(doc1);
var doc2 = {
_id : 2,
name : 'morris',
age : 22
};
db.findAndModify.insert(doc2);
 
var res = db.findAndModify.findAndModify({
query:{name:'morris'}, // 查询名字为morris的记录
sort:{age:1}, // 按age字段升序排列
update:{$inc:{age:1}}, // 更新查询到的第一条记录age字段加1
//'new':false, // 返回更新后的文档
upsert:true
});
printjson(res);
print("================");
var cursor = db.findAndModify.find();
cursor.forEach(printjson)
运行结果如下:
C:\>mongo --quiet findAndModify.js
{ "_id" : 1, "name" : "morris", "age" : 19 }
================
{ "_id" : 1, "name" : "morris", "age" : 20 }
{ "_id" : 2, "name" : "morris", "age" : 22 }
自增字段的实现
主键自动增长可以使向数据库添加数据时,不考虑主键的取值,记录插入后,数据库会自动为其分配一个值,确保绝对不会出现重复。大部分的关系型数据库都提供了主键自增的功能,例如,MySQL数据库可以使用AUTO_INCREMENT来很容易的实现字段自增。
由于MongoDB是为分布式存储而设计,_id主键默认使用的是Objectld类型的值,它比自增式主键更适合在分布式环境下使用,所以MongoDB默认不支持字段自增功能。
实现自增主键的功能,需要完成三个操作:
  • 取得当前最大_id值
  • 对id值加1
  • 修改原_id值
为防止多个客户端同时修改_id值,需要保证上面的三个操作以原子的方式进行自增。利用findAndModify函数的get-and-set的原子特性,来实现_id的自增。

自增字段的实例
var db = connect("localhost:27017/test");
db.couter.drop();
db.usertest.drop();
 
db.couter.insert({
_id:'userId',
seq:0
});
 
function nextval(name) {
var res = db.couter.findAndModify({
query:{_id:name},
update:{$inc:{seq:1}},
new:true,
upsert:true
});
return res.seq;
}
 
for(var i = 0; i < 5; i++) {
db.usertest.insert({
_id:nextval('userId'),
name:'morris'+i
});
}
 
var cursor = db.usertest.find();
printjson(cursor.toArray());
运行结果:
C:\>mongo --quiet auto_increment.js
[
{
"_id" : 1,
"name" : "morris0"
},
{
"_id" : 2,
"name" : "morris1"
},
{
"_id" : 3,
"name" : "morris2"
},
{
"_id" : 4,
"name" : "morris3"
},
{
"_id" : 5,
"name" : "morris4"
}
]


0 0
原创粉丝点击