findAndModify函数的介绍

操作,它的功能强大之处在于可以保证操作的原子性。

性操作是十分方便的,使用它可以实现一些简单的类事务操作。


findAndModify函数的使用

findAndModify函数有七个参数,每个参数含义如下表所示:

名称

作用

名称

作用

<document>

更新的条件

new:<boolean>

返回更新前的文档还是 更新后的文档

<document>

采用升序

<document>

要显示的字段

<boolean>

除文档

<document>

档进行更新

<boolean>

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值
  • 对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"
    
            }
    
    ]