根据mongodb官方文档介绍,如果在插入(insert)操作时,没有指定主键id,那么它会自动给插入行自动附上一个主键id。看起来不错,但是详细看看,就会发现这个id值有点复杂。
如下图:
mongdb把这个id称为ObjectId。
所以,如果我们想创建跟mysql的那种自动递增的主键,应该怎么操作呢?
如下图,就是我们想实现的效果图:
创建自动递增主键
利用mogodb命令行
1 /*part 1: 创建计数器表*/ 2 db.counters.insert({_id: "userid", seq: 0}) 3 4 /*part 2: 创建一个javascript函数 5 * from: http://www.runoob.com/mongodb/mongodb-intro.html 6 * MongoDB允许在服务端执行脚本,可以用Javascript编写某个函数,直接在服务端执行,也可以把函数的定义存储在服务端,下次直接调用即可。 7 * */ 8 function getNext(name) { 9 var ret = db.counters.findAndModify({ 10 query: {_id: name}, 11 update: {$inc: {seq: 1}}, 12 new: true, 13 upsert: true 14 }); 15 return ret.seq; 16 }; 17 /** 18 * part 3: 从计数器中分配一个主键id,然后插入一条记录到users表 19 */ 20 db.users.insert({_id: getNext("userid"), name: "hello world"})
利用php去实现
1 <?php 2 $dsn = "mongodb://127.0.0.1:27017"; 3 $mongo = new MongoClient($dsn); 4 5 $db = $mongo->selectDB("test"); 6 7 //执行mongo命令,并调用JavaScript函数。从counters表中分配一个users表的主键id 8 $ret = $db->command(array( 9 'findAndModify' => 'counters', 10 'query' => array('_id' => 'userid'), 11 'update' => array('$inc' => array('seq' => 1)), 12 'new' => true, 13 )); 14 15 //插入一条记录到users表 16 $id = $ret['value']['seq']; 17 $ret = $db->selectCollection('users')->insert(array( 18 '_id' => $id, 19 'name' => 'jason' 20 ));//
注意
1. mongodb对单文档的操作具有原子性,对多文档的操作不具有原子性,所以通过findAndModify进行+1(incr 1)的操作是安全的。
2. 从函数的角度来看,findAndModify比update更为强大,你看看它可以传递的参数个数就知道了。而在上面之所以选择findAndModify是因为这个函数可以返回操作后或者操作前整个document(相当于数据库的一行)的值。
相关知识点
2. php的MongoClient、MongoColletion、MongoDB类需要看看手册了