pymongo 聚合查询group

获取重复的手机号 db.weikephone.insert({"wid":100000185, "phone": 13818070900}) db.weikephone.insert({"wid":100000186, "phone": 13818070900}) db.weikephone.insert({"wid":100000187, "phone": 13818070901}) db.weikephone.insert({"wid":100000188, "phone": 13818070902}) [python] import pymongo mondb = pymongo.MongoClient('localhost',27017) mondb = mondb["test"] pipline = [ {"$group" : {"_id" : "$phone", "count" : {"$sum" : 1}}}, {"$match" : {"count" : {"$gt" : 1}}} ] print list(mondb.weikephone.aggregate(pipline)) [/python] 等同于 select phone,count(*) as count from t_wm_weikephone group by phone having count>1

PHP操作MongoDB

(“mongodb://用户名:密码 @地址:端口/默认指定数据库”,参数) $conn = new Mongo(); //可以简写为 //$conn=new Mongo(); #连接本地主机,默认端口. //$conn=new Mongo(“172.21.15.69″); #连接远程主机 //$conn=new Mongo(“xiaocai.loc:10086″); #连接指定端口远程主机 //$conn=new Mongo(“xiaocai.loc”,array(“replicaSet”=>true)); #负载均衡 //$conn=new Mongo(“xiaocai.loc”,array(“persist”=>”t”)); #持久连接 //$conn=new Mongo(“mongodb://sa:123@localhost”); #带用户名密码 //$conn=new Mongo(“mongodb://localhost:27017,localhost:27018″); #连接多个服务器 //$conn=new Mongo(“mongodb:///tmp/mongo-27017.sock”); #域套接字 //$conn=new Mongo(“mongodb://admin_miss:miss@localhost:27017/test”,array(‘persist’=>’p',”replicaSet”=>true)); #完整 //详细资料:http://www.php.net/manual/en/mongo.connecting.php //************************* //** 选择数据库与表 **// //************************* $db=$conn->mydb; #选择mydb数据库 //$db=$conn->selectDB(“mydb”); #第二种写法 $collection=$db->column; #选择集合(选择’表’) //$collection=$db->selectCollection(‘column’); #第二种写法 //$collection=$conn->mydb->column; #更简洁的写法 //注意:1.数据库和集合不需要事先创建,若它们不存在则会自动创建它们. // 2.注意错别字,你可能会无意间的创建一个新的数据库(与原先的数据库混乱). //************************* //** 插入文档 **// //************************* //**向集合中插入数据,返回bool判断是否插入成功. **/ $array=array(‘column_name’=>’col’.rand(100,999),’column_exp’=>’xiaocai’); $result=$collection->insert($array); #简单插入 echo “新记录ID:”.$array['_id']; #MongoDB会返回一个记录标识 var_dump($result); #返回:bool(true) //**向集合中安全插入数据,返回插入状态(数组). **/ $array=array(‘column_name’=>’col’.rand(100,999),’column_exp’=>’xiaocai2′); $result=$collection->insert($array,true); #用于等待MongoDB完成操作,以便确定是否成功.(当有大量记录插入时使用该参数会比较有用) echo “新记录ID:”.$array['_id']; #MongoDB会返回一个记录标识 var_dump($result); #返回:array(3) { ["err"]=> NULL ["n"]=> int(0) ["ok"]=> float(1) } //**完整的写法 **/ #insert($array,array(‘safe’=>false,’fsync’=>false,’timeout’=>10000)) /* * * * 完整格式:insert ( array $a [, array $options = array() ] ) * insert(array(),array(‘safe’=>false,’fsync’=>false,’timeout’=>10000)) * 参数:safe:默认false,是否安全写入 * fsync:默认false,是否强制插入到同步到磁盘 * timeout:超时时间(毫秒) * * 插入结果:{ “_id” : ObjectId(“4d63552ad549a02c01000009″), “column_name” : “col770″, “column_exp” : “xiaocai” } * ’_id’为主键字段,在插入是MongoDB自动添加. * * 注意:1.以下两次插入的为同一条记录(相同的_id),因为它们的值相同。 * $collection->insert(array(‘column_name’=>’xiaocai’)); * $collection->insert(array(‘column_name’=>’xiaocai’)); * 避免 * $collection->insert(array(‘column_name’=>’xiaocai’),true); * try { * $collection->insert(array(‘column_name’=>’xiaocai’),true); * }catch(MongoCursorException $e){ * echo “Can’t save the same person twice!\n”; * } * * 详细资料:http://www.php.net/manual/zh/mongocollection.insert.php * * */ //************************* //** 更新文档 **// //************************* //** 修改更新 **/ $where=array(‘column_name’=>’col123′); $newdata=array(‘column_exp’=>’GGGGGGG’,'column_fid’=>444); $result=$collection->update($where,array(‘$set’=>$newdata)); #$set:让某节点等于给定值,类似的还有$pull $pullAll $pop $inc,在后面慢慢说明用法 /* * 结果: * 原数据 * {“_id”:ObjectId(“4d635ba2d549a02801000003″),”column_name”:”col123″,”column_exp”:”xiaocai”} * 被替换成了 * {“_id”:ObjectId(“4d635ba2d549a02801000003″),”column_name”:”col123″,”column_exp”:”GGGGGGG”,”column_fid”:444} */ //** 替换更新 **/ $where=array(‘column_name’=>’col709′); $newdata=array(‘column_exp’=>’HHHHHHHHH’,'column_fid’=>123); $result=$collection->update($where,$newdata); /* * 结果: * 原数据 * {“_id”:ObjectId(“4d635ba2d549a02801000003″),”column_name”:”col709″,”column_exp”:”xiaocai”} * 被替换成了 * {“_id”:ObjectId(“4d635ba2d549a02801000003″),”column_exp”:”HHHHHHHHH”,”column_fid”:123} */ //** 批量更新 **/ $where=array(‘column_name’=>’col’); $newdata=array(‘column_exp’=>’multiple’,’91u’=>684435); $result=$collection->update($where,array(‘$set’=>$newdata),array(‘multiple’=>true)); /** * 所有’column_name’='col’都被修改 */ //** 自动累加 **/ $where=array(’91u’=>684435); $newdata=array(‘column_exp’=>’edit’); $result=$collection->update($where,array(‘$set’=>$newdata,’$inc’=>array(’91u’=>-5))); /** * 更新91u=684435的数据,并且91u自减5 */ /** 删除节点 **/ $where=array(‘column_name’=>’col685′); $result=$collection->update($where,array(‘$unset’=>’column_exp’)); /** * 删除节点column_exp */ /* * * * 完整格式:update(array $criteria, array $newobj [, array $options = array() ] ) * 注意:1.注意区分替换更新与修改更新 * 2.注意区分数据类型如 array(’91u’=>’684435′)与array(’91u’=>684435) * 详细资料:http://www.mongodb.org/display/DOCS/Updating#Updating-%24bit * * */ //************************* //** 删除文档 **// //************************* /** 清空数据库 **/ $collection->remove(array(‘column_name’=>’col399′)); //$collection->remove(); #清空集合 /** 删除指定MongoId **/ $id = new MongoId(“4d638ea1d549a02801000011″); $collection->remove(array(‘_id’=>(object)$id)); /* * * * 使用下面的方法来匹配{“_id”:ObjectId(“4d638ea1d549a02801000011″)},查询、更新也一样 * $id = new MongoId(“4d638ea1d549a02801000011″); * array(‘_id’=>(object)$id) * * */ //************************* //** 查询文档 **// //************************* /** 查询文档中的记录数 **/ echo ‘count:’.$collection->count().”
”; #全部 echo ‘count:’.$collection->count(array(‘type’=>’user’)).”
”; #可以加上条件 echo ‘count:’.$collection->count(array(‘age’=>array(‘$gt’=>50,’$lte’=>74))).”
”; #大于50小于等于74 echo ‘count:’.$collection->find()->limit(5)->skip(0)->count(true).”
”; #获得实际返回的结果数 /** * 注:$gt为大于、$gte为大于等于、$lt为小于、$lte为小于等于、$ne为不等于、$exists不存在 */ /** 集合中所有文档 **/ $cursor = $collection->find()->snapshot(); foreach ($cursor as $id => $value) { echo “$id: “; var_dump($value); echo “
”; } /** * 注意: * 在我们做了find()操作,获得$cursor游标之后,这个游标还是动态的. * 换句话说,在我find()之后,到我的游标循环完成这段时间,如果再有符合条件的记录被插入到collection,那么这些记录也会被$cursor 获得. * 如果你想在获得$cursor之后的结果集不变化,需要这样做: * $cursor = $collection->find(); * $cursor->snapshot(); * 详见http://www.bumao.com/index.php/2010/08/mongo_php_cursor.html */ /** 查询一条数据 **/ $cursor = $collection->findOne(); /** * 注意:findOne()获得结果集后不能使用snapshot(),fields()等函数; */ /** age,type 列不显示 **/ $cursor = $collection->find()->fields(array(“age”=>false,”type”=>false)); /** 只显示user 列 **/ $cursor = $collection->find()->fields(array(“user”=>true)); /** * 我这样写会出错:$cursor->fields(array(“age”=>true,”type”=>false)); */ /** (存在type,age节点) and age!=0 and age<50 **/ $where=array(‘type’=>array(‘$exists’=>true),’age’=>array(‘$ne’=>0,’$lt’=>50,’$exists’=>true)); $cursor = $collection->find($where); /** 分页获取结果集 **/ $cursor = $collection->find()->limit(5)->skip(0); /** 排序 **/ $cursor = $collection->find()->sort(array(‘age’=>-1,’type’=>1)); ##1表示降序 -1表示升序,参数的先后影响排序顺序 /** 索引 **/ $collection->ensureIndex(array(‘age’ => 1,’type’=>-1)); #1表示降序 -1表示升序 $collection->ensureIndex(array(‘age’ => 1,’type’=>-1),array(‘background’=>true)); #索引的创建放在后台运行(默认是同步运行) $collection->ensureIndex(array(‘age’ => 1,’type’=>-1),array(‘unique’=>true)); #该索引是唯一的 /** * ensureIndex (array(),array(‘name’=>’索引名称’,'background’=true,’unique’=true)) * 详见:http://www.php.net/manual/en/mongocollection.ensureindex.php */ /** 取得查询结果 **/ $cursor = $collection->find(); $array=array(); foreach ($cursor as $id => $value) { $array[]=$value; } //************************* //** 文档聚类 **// //************************* //这东西没弄明白… $conn->close(); #关闭连接 /* 关系型数据库与MongoDB数据存储的区别 MySql数据结构: CREATE TABLE IF NOT EXISTS `column`( `column_id` int(16) NOT NULL auto_increment COMMENT ‘主键’, `column_name` varchar(32) NOT NULL COMMENT ‘栏目名称’, PRIMARY KEY (`column_id`) ); CREATE TABLE IF NOT EXISTS `article`( `article_id` int(16) NOT NULL auto_increment COMMENT ‘主键’, `article_caption` varchar(15) NOT NULL COMMENT ‘标题’, PRIMARY KEY(`article_id`) ); CREATE TABLE IF NOT EXISTS `article_body`( `article_id` int(16) NOT NULL COMMENT ‘article.article_id’, `body` text COMMENT ‘正文’ ); MongoDB数据结构: $data=array( ‘column_name’ =>’default’, ‘article’ =>array( ‘article_caption’ => ‘xiaocai’, ‘body’ => ‘xxxxxxxxxx…’ ) ); $inc 如果记录的该节点存在,让该节点的数值加N;如果该节点不存在,让该节点值等于N 设结构记录结构为 array(’a’=>1,’b’=>’t’),想让a加5,那么: $coll->update( array(’b’=>’t’), array(’$inc’=>array(’a’=>5)), ) $set 让某节点等于给定值 设结构记录结构为 array(’a’=>1,’b’=>’t’),b为加f,那么: $coll->update( array(’a’=>1), array(’$set’=>array(’b’=>’f’)), ) $unset 删除某节点 设记录结构为 array(’a’=>1,’b’=>’t’),想删除b节点,那么: $coll->update( array(’a’=>1), array(’$unset’=>’b’), ) $push 如果对应节点是个数组,就附加一个新的值上去;不存在,就创建这个数组,并附加一个值在这个数组上;如果该节点不是数组,返回错误。 设记录结构为array(’a’=>array(0=>’haha’),’b’=& gt;1),想附加新数据到节点a,那么: $coll->update( array(’b’=>1), array(’$push’=>array(’a’=>’wow’)), ) 这样,该记录就会成为:array(’a’=>array(0=>’haha’,1=>’wow’),’b’=>1) $pushAll 与$push类似,只是会一次附加多个数值到某节点 $addToSet 如果该阶段的数组中没有某值,就添加之 设记录结构为array(’a’=>array(0=& gt;’haha’),’b’=>1),如果想附加新的数据到该节点a,那么: $coll->update( array(’b’=>1), array(’$addToSet’=>array(’a’=>’wow’)), ) 如果在a节点中已经有了wow,那么就不会再添加新的,如果没有,就会为该节点添加新的item——wow。 $pop 设该记录为array(’a’=>array(0=>’haha’,1=& gt;’wow’),’b’=>1) 删除某数组节点的最后一个元素: $coll->update( array(’b’=>1), array(’$pop=>array(’a’=>1)), ) 删除某数组阶段的第一个元素 $coll->update( array(’b’=>1), array(’$pop=>array(’a’=>-1)), ) $pull 如果该节点是个数组,那么删除其值为value的子项,如果不是数组,会返回一个错误。 设该记录为 array(’a’=>array(0=>’haha’,1=>’wow’),’b’=>1),想要删除a中value为 haha的子项: $coll->update( array(’b’=>1), array(’$pull=>array(’a’=>’haha’)), ) 结果为: array(’a’=>array(0=>’wow’),’b’=>1) $pullAll 与$pull类似,只是可以删除一组符合条件的记录。 */ ?> (“mongodb://用户名:密码 @地址:端口/默认指定数据库”,参数) $conn = new Mongo(); //可以简写为 //$conn=new Mongo(); #连接本地主机,默认端口. //$conn=new Mongo(“172.21.15.69″); #连接远程主机 //$conn=new Mongo(“xiaocai.loc:10086″); #连接指定端口远程主机 //$conn=new Mongo(“xiaocai.loc”,array(“replicaSet”=>true)); #负载均衡 //$conn=new Mongo(“xiaocai.loc”,array(“persist”=>”t”)); #持久连接 //$conn=new Mongo(“mongodb://sa:123@localhost”); #带用户名密码 //$conn=new Mongo(“mongodb://localhost:27017,localhost:27018″); #连接多个服务器 //$conn=new Mongo(“mongodb:///tmp/mongo-27017.sock”); #域套接字 //$conn=new Mongo(“mongodb://admin_miss:miss@localhost:27017/test”,array(‘persist’=>’p',”replicaSet”=>true)); #完整 //详细资料:http://www.php.net/manual/en/mongo.connecting.php //************************* //** 选择数据库与表 **// //************************* $db=$conn->mydb; #选择mydb数据库 //$db=$conn->selectDB(“mydb”); #第二种写法 $collection=$db->column; #选择集合(选择’表’) //$collection=$db->selectCollection(‘column’); #第二种写法 //$collection=$conn->mydb->column; #更简洁的写法 //注意:1.数据库和集合不需要事先创建,若它们不存在则会自动创建它们. // 2.注意错别字,你可能会无意间的创建一个新的数据库(与原先的数据库混乱). //************************* //** 插入文档 **// //************************* //**向集合中插入数据,返回bool判断是否插入成功. **/ $array=array(‘column_name’=>’col’.rand(100,999),’column_exp’=>’xiaocai’); $result=$collection->insert($array); #简单插入 echo “新记录ID:”.$array['_id']; #MongoDB会返回一个记录标识 var_dump($result); #返回:bool(true) //**向集合中安全插入数据,返回插入状态(数组). **/ $array=array(‘column_name’=>’col’.rand(100,999),’column_exp’=>’xiaocai2′); $result=$collection->insert($array,true); #用于等待MongoDB完成操作,以便确定是否成功.(当有大量记录插入时使用该参数会比较有用) echo “新记录ID:”.$array['_id']; #MongoDB会返回一个记录标识 var_dump($result); #返回:array(3) { ["err"]=> NULL ["n"]=> int(0) ["ok"]=> float(1) } //**完整的写法 **/ #insert($array,array(‘safe’=>false,’fsync’=>false,’timeout’=>10000)) /* * * * 完整格式:insert ( array $a [, array $options = array() ] ) * insert(array(),array(‘safe’=>false,’fsync’=>false,’timeout’=>10000)) * 参数:safe:默认false,是否安全写入 * fsync:默认false,是否强制插入到同步到磁盘 * timeout:超时时间(毫秒) * * 插入结果:{ “_id” : ObjectId(“4d63552ad549a02c01000009″), “column_name” : “col770″, “column_exp” : “xiaocai” } * ’_id’为主键字段,在插入是MongoDB自动添加. * * 注意:1.以下两次插入的为同一条记录(相同的_id),因为它们的值相同。 * $collection->insert(array(‘column_name’=>’xiaocai’)); * $collection->insert(array(‘column_name’=>’xiaocai’)); * 避免 * $collection->insert(array(‘column_name’=>’xiaocai’),true); * try { * $collection->insert(array(‘column_name’=>’xiaocai’),true); * }catch(MongoCursorException $e){ * echo “Can’t save the same person twice!\n”; * } * * 详细资料:http://www.php.net/manual/zh/mongocollection.insert.php * * */ //************************* //** 更新文档 **// //************************* //** 修改更新 **/ $where=array(‘column_name’=>’col123′); $newdata=array(‘column_exp’=>’GGGGGGG’,'column_fid’=>444); $result=$collection->update($where,array(‘$set’=>$newdata)); #$set:让某节点等于给定值,类似的还有$pull $pullAll $pop $inc,在后面慢慢说明用法 /* * 结果: * 原数据 * {“_id”:ObjectId(“4d635ba2d549a02801000003″),”column_name”:”col123″,”column_exp”:”xiaocai”} * 被替换成了 * {“_id”:ObjectId(“4d635ba2d549a02801000003″),”column_name”:”col123″,”column_exp”:”GGGGGGG”,”column_fid”:444} */ //** 替换更新 **/ $where=array(‘column_name’=>’col709′); $newdata=array(‘column_exp’=>’HHHHHHHHH’,'column_fid’=>123); $result=$collection->update($where,$newdata); /* * 结果: * 原数据 * {“_id”:ObjectId(“4d635ba2d549a02801000003″),”column_name”:”col709″,”column_exp”:”xiaocai”} * 被替换成了 * {“_id”:ObjectId(“4d635ba2d549a02801000003″),”column_exp”:”HHHHHHHHH”,”column_fid”:123} */ //** 批量更新 **/ $where=array(‘column_name’=>’col’); $newdata=array(‘column_exp’=>’multiple’,’91u’=>684435); $result=$collection->update($where,array(‘$set’=>$newdata),array(‘multiple’=>true)); /** * 所有’column_name’='col’都被修改 */ //** 自动累加 **/ $where=array(’91u’=>684435); $newdata=array(‘column_exp’=>’edit’); $result=$collection->update($where,array(‘$set’=>$newdata,’$inc’=>array(’91u’=>-5))); /** * 更新91u=684435的数据,并且91u自减5 */ /** 删除节点 **/ $where=array(‘column_name’=>’col685′); $result=$collection->update($where,array(‘$unset’=>’column_exp’)); /** * 删除节点column_exp */ /* * * * 完整格式:update(array $criteria, array $newobj [, array $options = array() ] ) * 注意:1.注意区分替换更新与修改更新 * 2.注意区分数据类型如 array(’91u’=>’684435′)与array(’91u’=>684435) * 详细资料:http://www.mongodb.org/display/DOCS/Updating#Updating-%24bit * * */ //************************* //** 删除文档 **// //************************* /** 清空数据库 **/ $collection->remove(array(‘column_name’=>’col399′)); //$collection->remove(); #清空集合 /** 删除指定MongoId **/ $id = new MongoId(“4d638ea1d549a02801000011″); $collection->remove(array(‘_id’=>(object)$id)); /* * * * 使用下面的方法来匹配{“_id”:ObjectId(“4d638ea1d549a02801000011″)},查询、更新也一样 * $id = new MongoId(“4d638ea1d549a02801000011″); * array(‘_id’=>(object)$id) * * */ //************************* //** 查询文档 **// //************************* /** 查询文档中的记录数 **/ echo ‘count:’.$collection->count().”
”; #全部 echo ‘count:’.$collection->count(array(‘type’=>’user’)).”
”; #可以加上条件 echo ‘count:’.$collection->count(array(‘age’=>array(‘$gt’=>50,’$lte’=>74))).”
”; #大于50小于等于74 echo ‘count:’.$collection->find()->limit(5)->skip(0)->count(true).”
”; #获得实际返回的结果数 /** * 注:$gt为大于、$gte为大于等于、$lt为小于、$lte为小于等于、$ne为不等于、$exists不存在 */ /** 集合中所有文档 **/ $cursor = $collection->find()->snapshot(); foreach ($cursor as $id => $value) { echo “$id: “; var_dump($value); echo “
”; } /** * 注意: * 在我们做了find()操作,获得$cursor游标之后,这个游标还是动态的. * 换句话说,在我find()之后,到我的游标循环完成这段时间,如果再有符合条件的记录被插入到collection,那么这些记录也会被$cursor 获得. * 如果你想在获得$cursor之后的结果集不变化,需要这样做: * $cursor = $collection->find(); * $cursor->snapshot(); * 详见http://www.bumao.com/index.php/2010/08/mongo_php_cursor.html */ /** 查询一条数据 **/ $cursor = $collection->findOne(); /** * 注意:findOne()获得结果集后不能使用snapshot(),fields()等函数; */ /** age,type 列不显示 **/ $cursor = $collection->find()->fields(array(“age”=>false,”type”=>false)); /** 只显示user 列 **/ $cursor = $collection->find()->fields(array(“user”=>true)); /** * 我这样写会出错:$cursor->fields(array(“age”=>true,”type”=>false)); */ /** (存在type,age节点) and age!=0 and age<50 **/ $where=array(‘type’=>array(‘$exists’=>true),’age’=>array(‘$ne’=>0,’$lt’=>50,’$exists’=>true)); $cursor = $collection->find($where); /** 分页获取结果集 **/ $cursor = $collection->find()->limit(5)->skip(0); /** 排序 **/ $cursor = $collection->find()->sort(array(‘age’=>-1,’type’=>1)); ##1表示降序 -1表示升序,参数的先后影响排序顺序 /** 索引 **/ $collection->ensureIndex(array(‘age’ => 1,’type’=>-1)); #1表示降序 -1表示升序 $collection->ensureIndex(array(‘age’ => 1,’type’=>-1),array(‘background’=>true)); #索引的创建放在后台运行(默认是同步运行) $collection->ensureIndex(array(‘age’ => 1,’type’=>-1),array(‘unique’=>true)); #该索引是唯一的 /** * ensureIndex (array(),array(‘name’=>’索引名称’,'background’=true,’unique’=true)) * 详见:http://www.php.net/manual/en/mongocollection.ensureindex.php */ /** 取得查询结果 **/ $cursor = $collection->find(); $array=array(); foreach ($cursor as $id => $value) { $array[]=$value; } //************************* //** 文档聚类 **// //************************* //这东西没弄明白… $conn->close(); #关闭连接 /* 关系型数据库与MongoDB数据存储的区别 MySql数据 结构: CREATE TABLE IF NOT EXISTS `column`( `column_id` int(16) NOT NULL auto_increment COMMENT ‘主键’, `column_name` varchar(32) NOT NULL COMMENT ‘栏目名称’, PRIMARY KEY (`column_id`) ); CREATE TABLE IF NOT EXISTS `article`( `article_id` int(16) NOT NULL auto_increment COMMENT ‘主键’, `article_caption` varchar(15) NOT NULL COMMENT ‘标题’, PRIMARY KEY(`article_id`) ); CREATE TABLE IF NOT EXISTS `article_body`( `article_id` int(16) NOT NULL COMMENT ‘article.article_id’, `body` text COMMENT ‘正文’ ); MongoDB数据结构: $data=array( ‘column_name’ =>’default’, ‘article’ =>array( ‘article_caption’ => ‘xiaocai’, ‘body’ => ‘xxxxxxxxxx…’ ) ); $inc 如果记录的该节点存在,让该节点的数值加N;如果该节点不存在,让该节点值等 于N 设结构记录结构为 array(’a’=>1,’b’=>’t’),想让a加5,那么: $coll->update( array(’b’=>’t’), array(’$inc’=>array(’a’=>5)), ) $set 让某节点等于给定值 设结构记录结构为 array(’a’=>1,’b’=>’t’),b为加f,那么: $coll->update( array(’a’=>1), array(’$set’=>array(’b’=>’f’)), ) $unset 删除某节点 设记录结构为 array(’a’=>1,’b’=>’t’),想删除b节点,那么: $coll->update( array(’a’=>1), array(’$unset’=>’b’), ) $push 如果对应节点是个数组,就附加一个新的值上去;不存在,就创建这个数组,并附加一个值在这个数组上;如果 该节点不是数组,返回错误。 设记录结构为array(’a’=>array(0=>’haha’),’b’=& gt;1),想附加新数据到节点a,那么: $coll->update( array(’b’=>1), array(’$push’=>array(’a’=>’wow’)), ) 这 样,该记录就会成为:array(’a’=>array(0=>’haha’,1=>’wow’),’b’=>1) $pushAll 与$push类似,只是会一次附加多个数值到某节点 $addToSet 如果该阶段的数组中没有某值,就添加之 设记录结构为array(’a’=>array(0=& gt;’haha’),’b’=>1),如果想附加新的数据到该节点a,那么: $coll->update( array(’b’=>1), array(’$addToSet’=>array(’a’=>’wow’)), ) 如果在a节点中已经有了wow,那么就不会再添加新的,如果没有,就会为该节点添加新的item——wow。 $pop 设该记录为array(’a’=>array(0=>’haha’,1=& gt;’wow’),’b’=>1) 删除某数组节点的最后一个元素: $coll->update( array(’b’=>1), array(’$pop=>array(’a’=>1)), ) 删除某数组阶段的第一个元素 $coll->update( array(’b’=>1), array(’$pop=>array(’a’=>-1)), ) $pull 如果该节点是个数组,那么删除其值为value的子项,如果不是数组,会返回一个错误。 设该记录为 array(’a’=>array(0=>’haha’,1=>’wow’),’b’=>1),想要删除a中value为 haha的子项: $coll->update( array(’b’=>1), array(’$pull=>array(’a’=>’haha’)), ) 结 果为: array(’a’=>array(0=>’wow’),’b’=>1) $pullAll 与$pull类似,只是可以删除一组符合条件的记录。 */ ?>

mongoDB-python

import pymongo
con = pymongo.Connection('localhost', 27017)

mydb = con.mydb # new a database
mydb.add_user('test', 'test') # add a user
mydb.authenticate('test', 'test') # check auth

muser = mydb.user # new a table

muser.save({'id':1, 'name':'test'}) # add a record

muser.insert({'id':2, 'name':'hello'}) # add a record
muser.find_one() # find a record

muser.find_one({'id':2}) # find a record by query

muser.create_index('id')

muser.find().sort('id', pymongo.ASCENDING) # DESCENDING
# muser.drop() delete table
muser.find({'id':1}).count() # get records number

muser.find({'id':1}).limit(3).skip(2) # start index is 2 limit 3 records

muser.remove({'id':1}) # delet records where id = 1

muser.update({'id':2}, {'$set':{'name':'haha'}}) # update one recor



mongo –path db.AddUser(username,password) 添加用户 db.auth(usrename,password) 设置数据库连接验证 db.cloneDataBase(fromhost) 从目标服务器克隆一个数据库 db.commandHelp(name) returns the help for the command db.copyDatabase(fromdb,todb,fromhost) 复制数据库fromdb—源数据库名称,todb—目标数据库名称,fromhost—源数据库服务器地址 db.createCollection(name,{size:3333,capped:333,max:88888}) 创建一个数据集,相当于一个表 db.currentOp() 取消当前库的当前操作 db.dropDataBase() 删除当前数据库 db.eval(func,args) run code server-side db.getCollection(cname) 取得一个数据集合,同用法:db['cname'] or db.cname db.getCollenctionNames() 取得所有数据集合的名称列表 db.getLastError() 返回最后一个错误的提示消息 db.getLastErrorObj() 返回最后一个错误的对象 db.getMongo() 取得当前服务器的连接对象get the server connection object db.getMondo().setSlaveOk() allow this connection to read from then nonmaster membr of a replica pair db.getName() 返回当操作数据库的名称 db.getPrevError() 返回上一个错误对象 db.getProfilingLevel() ?什么等级 db.getReplicationInfo() ?什么信息 db.getSisterDB(name) get the db at the same server as this onew db.killOp() 停止(杀死)在当前库的当前操作 db.printCollectionStats() 返回当前库的数据集状态 db.printReplicationInfo() db.printSlaveReplicationInfo() db.printShardingStatus() 返回当前数据库是否为共享数据库 db.removeUser(username) 删除用户 db.repairDatabase() 修复当前数据库 db.resetError() db.runCommand(cmdObj) run a database command. if cmdObj is a string, turns it into {cmdObj:1} db.setProfilingLevel(level) 0=off,1=slow,2=all db.shutdownServer() 关闭当前服务程序 db.version() 返回当前程序的版本信息 db.linlin.find({id:10}) 返回linlin数据集ID=10的数据集 db.linlin.find({id:10}).count() 返回linlin数据集ID=10的数据总数 db.linlin.find({id:10}).limit(2)返回linlin数据集ID=10的数据集从第二条开始的数据集 db.linlin.find({id:10}).skip(8) 返回linlin数据集ID=10的数据集从0到第八条的数据集 db.linlin.find({id:10}).limit(2).skip(8) 返回linlin数据集ID=1=的数据集从第二条到第八条的数据 db.linlin.find({id:10}).sort() 返回linlin数据集ID=10的排序数据集 db.linlin.findOne([query]) 返回符合条件的一条数据 db.linlin.getDB() 返回此数据集所属的数据库名称 db.linlin.getIndexes() 返回些数据集的索引信息 db.linlin.group({key:…,initial:…,reduce:…[,cond:...]}) db.linlin.mapReduce(mayFunction,reduceFunction, ) db.linlin.remove(query) 在数据集中删除一条数据 db.linlin.renameCollection(newName) 重命名些数据集名称 db.linlin.save(obj) 往数据集中插入一条数据 db.linlin.stats() 返回此数据集的状态 db.linlin.storageSize() 返回此数据集的存储大小 db.linlin.totalIndexSize() 返回此数据集的索引文件大小 db.linlin.totalSize() 返回些数据集的总大小 db.linlin.update(query,object[,upsert_bool])在此数据集中更新一条数据 db.linlin.validate() 验证此数据集 db.linlin.getShardVersion() 返回数据集共享版本号 db.linlin.find({‘name’:'foobar’}) select * from linlin where name=’foobar’ db.linlin.find() select * from linlin db.linlin.find({‘ID’:10}).count() select count(*) from linlin where ID=10 db.linlin.find().skip(10).limit(20) 从查询结果的第十条开始读20条数据 select * from linlin limit 10,20 ———-mysql db.linlin.find({‘ID’:{in:[25,35,45]}}) select * from linlin where ID in (25,35,45) db.linlin.find().sort({‘ID’:-1}) select * from linlin order by ID desc db.linlin.distinct(‘name’,{‘ID’:{lt:20}}) select distinct(name) from linlin where ID<20 db.linlin.group({key:{'name':true},cond:{'name':'foo'},reduce:function(obj,prev){prev.msum+=obj.marks;},initial:{msum:0}}) select name,sum(marks) from linlin group by name db.linlin.find('this.ID<20′,{name:1}) select name from linlin where ID<20 db.linlin.insert({'name':'foobar’,'age':25}) insert into linlin ('name','age’)values('foobar',25) db.linlin.insert({'name':'foobar’,'age':25,’email’:'cclove2@163.com’}) db.linlin.remove({}) delete * from linlin db.linlin.remove({'age':20}) delete linlin where age=20 db.linlin.remove({'age':{lt:20}}) delete linlin where age<20 db.linlin.remove({'age':{lte:20}}) delete linlin where age<=20 db.linlin.remove({'age':{gt:20}}) delete linlin where age>20 db.linlin.remove({‘age’:{gte:20}}) delete linlin where age>=20 db.linlin.remove({‘age’:{ne:20}}) delete linlin where age!=20 db.linlin.update({‘name’:'foobar’},{‘set’:{‘age’:36}}) update linlin set age=36 where name=’foobar’ db.linlin.update({‘name’:'foobar’},{‘$inc’:{‘age’:3}}) update linlin set age=age+3 where name=’foobar’

mongodo 权限认证

1. 在开启MongoDB 服务时不添加任何参数时,可以对数据库任意操作,而且可以远程访问数据库。如果启动的时候指定—auth参数,可以对数据库进行用户验证            $ ./mongod --auth >> mongodb.log & 开启            ./mongo MongoDB shell version: 1.8.1 connecting to: test >show dbs admin   (empty) local   (empty)

2. 添加用户

在刚安装完毕的时候MongoDB都默认有一个admin数据库,而admin.system.users中将会保存比在其它数据库中设置的用户权限更大的用户信息。

当admin.system.users中一个用户都没有时,即使mongod启动时添加了--auth参数,如果没有在admin数据库中添加用户,此时不进行任何认证还是可以做任何操作,直到在admin.system.users中添加了一个用户。 下面创建数据库tage,并给tage创建用户: > use tage    switched to db tage > db.addUser("tage","123") {          "user" : "tage",          "readOnly" : false,          "pwd" : "1f66d5c4223029536080d41febe0ec33" } 在admin库中创建root用户: > use admin switched to db admin > db.addUser("root","123456") {          "user" : "root",          "readOnly" : false,          "pwd" : "34e5772aa66b703a319641d42a47d696" } 3. 验证用户: > db.auth("root","123") 0                    密码错误,返回0,验证失败 > db.auth("root","123456")   1                                            验证成功,返回1   下面试验用户权限设置: $ ./mongo       登录时不加用户名与密码 MongoDB shell version: 1.8.1 connecting to: test > use tage switched to db tage > db.system.users.find() error: {          "$err" : "unauthorized db:tage lock type:-1 client:127.0.0.1",          "code" : 10057 } 4. 以上验证说明,登录时不指定用户名与密码,就会报错。下面指定用户与密码 $ ./mongo -uroot -p123456  指定用户与密码,但是不指定库名 MongoDB shell version: 1.8.1 connecting to: test Wed Aug  3 21:30:42 uncaught exception: login failed exception: login failed mongodb登录时默认连接test库,如果登录时不指定库名,就会报错 5. 下面以tage库的用户名登录进行验证: $ ./mongo tage -utage -p123 MongoDB shell version: 1.8.1 connecting to: tage > db.system.users.find()    对所属自己的库进行操作,有权限 { "_id" : ObjectId("4e394c696b50a56254359088"), "user" : "tage", "readOnly" : false, "pwd" : "1f66d5c4223029536080d41febe0ec33" } > use admin switched to db admin > db.system.users.find() 对其他库操作,没有权限 error: {          "$err" : "unauthorized db:admin lock type:-1 client:127.0.0.1",          "code" : 10057 } 6. 下面以admin库下的root用户登录进行验证: ./mongo admin -uroot -p123456 MongoDB shell version: 1.8.1 connecting to: admin > db.system.users.find() { "_id" : ObjectId("4e394caf6b50a56254359089"), "user" : "root", "readOnly" : false, "pwd" : "34e5772aa66b703a319641d42a47d696" } > use tage switched to db tage > db.system.users.find()   对其他库进行操作,有权限 { "_id" : ObjectId("4e394c696b50a56254359088"), "user" : "tage", "readOnly" : false, "pwd" : "1f66d5c4223029536080d41febe0ec33" } 7. mongodb的远程用户连接 语法结构:mongo –uusername –ppwd ServerIP:port/dbname 其中port默认为27017 $ ./mongo  -uroot -p123456 192.168.2.150/admin MongoDB shell version: 1.8.1 connecting to: 192.168.2.150/admin > db.system.users.find() { "_id" : ObjectId("4e394caf6b50a56254359089"), "user" : "root", "readOnly" : false, "pwd" : "34e5772aa66b703a319641d42a47d696" }

mongodb 管理

1.  启动和停止MongoDB: 执行mongod命令启动MongoDB服务器。mongod有很多可配置的选项,我们通过mongod --help可以查看所有选项,这里仅介绍一些主要选项: --dbpath: 缺省情况下数据库的数据目录为/data/db。对于Windows平台,如果当前的可执行文件位于D盘,那么其缺省数据目录为D:\data\db。我们可以通过这个选项为服务程序重新指定数据目录。如果当前主机运行多个mongod,那么必须为每个服务程序指定不同的数据目录,因为当mongod启动成功之后,会在数据目录下创建一个mongod.lock的文件,该文件用于防止其它mongod进程数据该数据目录。如: mongod --dbpath=D:/data2/db --port 缺省情况下的默认端口号是27017。同样当有多个mongod服务程序在同一台主机同时运行时,则需要为它们分别指定不同的监听端口。如: mongod --port=29017 --fork 以守护进程的方式运行MongoDB。 --logpath 指定日志输出路径,而不是输出到命令行。如果对文件夹有写权限的话,系统会在文件不存在时创建它。它会将已有文件覆盖掉,清除所有原来的日志记录。如果想保留原来的日志,还需要使用--logappend选项。如: /> mongod --logpath=D:\logdata\mylog.log all output going to: D:\logdata\mylog.log 需要说明的是,对于上例,logdata目录必须被提前手工创建,否则mongod将执行启动失败。 --config 指定配置文件,用于加载命令行未指定的各种选项。如: mongod --config=D:\mydb.conf 配置文件的示例内容如下: port = 29017 fork = true   #这里的井号表示注释部分,对于fork这种命令行选项,需要用true来表示打开了。 logpath = D:\mylog\db.log 通常情况下,我们都是希望将mongodb server优雅的关闭。如果服务程序运行于前台,那么直接CTRL+C即可。如果是后台,那么可以通过SIGINT和SIGTERM信号来通知服务程序准备退出,服务器在收到信号后,会先妥善的安排退出前的数据和状态保存工作,如:正常的关闭当前的连接、将缓存中的数据刷新到磁盘等。在完成所有这些工作之后,服务器正常停止。如: /> pkill mongod /> pkill -2 mongod 切记不要直接执行下面的命令: /> pkill -9 mongod 该信号将会导致mongodb server强制性立即退出。 除了上述方法之外,我们还可以通过mongo客户端工具通知服务器正常退出,如: > use admin switched to db admin > db.shutdownServer() 2、服务器状态监控: C:\Mine\ThirdParty\mongodb\bin>mongostat connected to: 127.0.0.1 insert  query update delete getmore command flushes mapped  vsize    ... ... 0      0      0      0       0       1       0     0m   100m    ... ... 0      0      0      0       0       1       0     0m   100m    ... ... 0      0      0      0       0       1       0     0m   100m    ... ... 0      0      0      0       0       1       0     0m   100m    ... ... 0      0      0      0       0       1       0     0m   100m    ... ... 0      0      0      0       0       1       0     0m   100m    ... ... 0      0      0      0       0       1       0     0m   100m    ... ... 0      0      0      0       0       1       0     0m   100m    ... ... 原文 http://www.cnblogs.com/stephen-liu74/archive/2012/09/22/2658670.html

mongodb 聚合

MongoDB除了基本的查询功能之外,还提供了强大的聚合功能。这里主要介绍count、distinct和group。 1. count: --在空集合中,count返回的数量为0。 > db.test.count() 0     --测试插入一个文档后count的返回值。 > db.test.insert({"test":1}) > db.test.count() 1 > db.test.insert({"test":2}) > db.test.count() 2     --count和find一样,也接受条件。从结果可以看出,只有符合条件的文档参与了计算。 > db.test.count({"test":1}) 1 2. distinct: distinct用来找出给定键的所有不同的值。使用时也必须指定集合和键。     --为了便于后面的测试,先清空测试集合。 > db.test.remove() > db.test.count() 0     --插入4条测试数据。请留意Age字段。 > db.test.insert({"name":"Ada", "age":20}) > db.test.insert({"name":"Fred", "age":35}) > db.test.insert({"name":"Andy", "age":35}) > db.test.insert({"name":"Susan", "age":60})     --distinct命令必须指定集合名称,如test,以及需要区分的字段,如:age。     --下面的命令将基于test集合中的age字段执行distinct命令。 > db.runCommand({"distinct":"test", "key":"age"}) { "values" : [ 20, 35, 60 ], "stats" : { "n" : 4, "nscanned" : 4, "nscannedObjects" : 4, "timems" : 0, "cursor" : "BasicCursor" }, "ok" : 1 } 3. group: group做的聚合有些复杂。先选定分组所依据的键,此后MongoDB就会将集合依据选定键值的不同分成若干组。然后可以通过聚合每一组内的文档,产生一个结果文档。     --这里是准备的测试数据 > db.test.remove() > db.test.insert({"day" : "2012-08-20", "time" : "2012-08-20 03:20:40", "price" : 4.23}) > db.test.insert({"day" : "2012-08-21", "time" : "2012-08-21 11:28:00", "price" : 4.27}) > db.test.insert({"day" : "2012-08-20", "time" : "2012-08-20 05:00:00", "price" : 4.10}) > db.test.insert({"day" : "2012-08-22", "time" : "2012-08-22 05:26:00", "price" : 4.30}) > db.test.insert({"day" : "2012-08-21", "time" : "2012-08-21 08:34:00", "price" : 4.01})     --这里将用day作为group的分组键,然后取出time键值为最新时间戳的文档,同时也取出该文档的price键值。 > db.test.group( { ... "key" : {"day":true},           --如果是多个字段,可以为{"f1":true,"f2":true} ... "initial" : {"time" : "0"},       --initial表示$reduce函数参数prev的初始值。每个组都有一份该初始值。 ... "$reduce" : function(doc,prev) {  --reduce函数接受两个参数,doc表示正在迭代的当前文档,prev表示累加器文档。 ...     if (doc.time > prev.time) { ...         prev.day = doc.day ...         prev.price = doc.price; ...         prev.time = doc.time; ...     } ... } } ) [ { "day" : "2012-08-20", "time" : "2012-08-20 05:00:00", "price" : 4.1 }, { "day" : "2012-08-21", "time" : "2012-08-21 11:28:00", "price" : 4.27 }, { "day" : "2012-08-22", "time" : "2012-08-22 05:26:00", "price" : 4.3 } ]    --下面的例子是统计每个分组内文档的数量。 > db.test.group( { ... key: { day: true}, ... initial: {count: 0}, ... reduce: function(obj,prev){ prev.count++;}, ... } ) [ { "day" : "2012-08-20", "count" : 2 }, { "day" : "2012-08-21", "count" : 2 }, { "day" : "2012-08-22", "count" : 1 } ]    --最后一个是通过完成器修改reduce结果的例子。 > db.test.group( { ... key: { day: true}, ... initial: {count: 0}, ... reduce: function(obj,prev){ prev.count++;}, ... finalize: function(out){ out.scaledCount = out.count * 10 } --在结果文档中新增一个键。 ... } ) [ { "day" : "2012-08-20", "count" : 2, "scaledCount" : 20 }, { "day" : "2012-08-21", "count" : 2, "scaledCount" : 20 }, { "day" : "2012-08-22", "count" : 1, "scaledCount" : 10 } ]   原文 http://www.cnblogs.com/stephen-liu74/archive/2012/09/19/2652308.html

mongodb 学习

一、文档的注意事项: 1.  键值对是有序的,如:{ "name" : "stephen", "genda" : "male" } 不等于 { "genda" : "male", "name" : "stephen" } 2.  文档信息是大小写敏感的,如:{ "name" : "stephen" } 不等于 { "Name" : "stephen" } 3.  文档信息是区分类型的,如:{ "age" : 30 } 不等于 { "age" : "30" } 4.  文档中不能出现重复键,如:{ "name" : "stephen", "name" : "liu" } 二、使用多个集合的必要性: 1.  如果把各种模式的文档存放在一个集合中,对于开发者来说是非常灾难的。因为在获取到查询结果之后,就需要手工编写代码过滤不同类型的文档了。 2.  会使查询效率降低。试想一下,假设某个模式的文档的数据量相对较少,如果仍然将其放到一个通用的大集合中,其查询效率势必会大大低于将其放到独立的集合中。 3.  在创建索引时,如果所有的文档均为同一模式,那么索引的利用率将会更加高效。 三、集合的命名注意事项: 1.  集合名不能是空字符串""。 2.  不要以system开头,这一般是为系统保留的,如system.users集合中保存了数据库的用户信息,而system.namespace集合中保留了数据库集合的信息。 3.  不要在集合名里面包含'$'字符。 4.  子集合只是一种较好的集合规划方式,如blog.posts和blog.anthurs,实际上它们和blog集合之间没有任何关系,甚至blog集合可以不存在。 四、数据库: 在同一个MongoDB服务器中可以存在多个数据库,每个不同的数据库存储在不同的文件中。又由于数据库名和文件名是绑定的,因此数据库名会有一些限制。 1.  不能是空字符""。 2.  全部小写且不超过64字节。 3.  不得含有文件名命名中的非法字符。 4.  admin数据库是管理数据库,如果某个用户位于该数据库中,他将自动继承所有数据库权限。一些特定的服务器命令也只能从这个数据库运行。 5.  local这个数据库永远不会被复制,只是用于存储限于本地单台服务器的任意集合。 6.  数据库名.集合名,表示该集合的完全限定名,其长度不要超过121自己。 五:MongoDB的启动: 1.  直接执行mongod即可,在没有任何命令行参数的情况下,服务器的主机中必须包含/data/db目录,对于Windows而言,其缺省目录则为服务程序所在驱动器的\data\db。如D盘,则为D:\data\bin。缺省监听端口为27017。 2.  MongoDB自带了一个JavaScript Shell,可以从命令行与MongoDB交互。如:mongo。这个Shell工具可以直接执行简单的数学运算。如: > x = 200 200 > x /5 40 --还可以调用JavaScript的标准库。 > new Date("2012/05/05") ISODate("2012-05-04T16:00:00Z") > "Hello World".replace("World", "MongoDB") Hello MongoDB --定义和调用自定义的JavaScript函数。 > function factorial(n) { ... if (n <= 1) return 1 ... return n * factorial(n - 1) ... } > factorial(5) 120 3.  在Shell客户端插入MongoDB的文档,如: > post = { "title" : "my blog post", "content" : "Here's my blog", "date" : new Date() } { "title" : "my blog post", "content" : "Here's my blog", "date" : ISODate("2012-06-04T07:38:51.345Z") } > db.blog.insert(post) > db.blog.find() { "_id" : ObjectId("4fcc661de4bcbac15b3d9e3a"), "title" : "my blog post", "content" : "Here's my blog", "date" : ISODate("2012-06-04T07:38:51.345Z") } 4.  在Shell客户端查询文档,如: > db.blog.findOne() { "_id" : ObjectId("4fcc661de4bcbac15b3d9e3a"), "title" : "my blog post", "content" : "Here's my blog", "date" : ISODate("2012-06-04T07:38:51.345Z") } 5.  在Shell中更新文档,如: --需要先更新post变量的内容,即先增加了一个comments的键,其值为空数组。 > post.comments = [] [ ] --update的第一个参数是条件,第二个参数是待更新的值。 > db.blog.update({ "title" : "my blog post"}, post) > db.blog.findOne() { "_id" : ObjectId("4fcc661de4bcbac15b3d9e3a"), "title" : "my blog post", "content" : "Here's my blog", "date" : ISODate("2012-06-04T07:38:51.345Z"), "comments" : [ ] } 6.  在Shell客户端中删除,如: --如果remove中没有条件,则清除集合中的全部数据。 > db.blog.remove( { title:"my blog post"}) > db.blog.findOne() null 六、Shell的使用小技巧: > show dbs  --显示数据库名。 > show collections --显示集合名 > show users --显示用户名 > db.help()  --列出数据库的方法。 > db.blog.help() --列出blog集合上的方法。 > db.blog.update --可以直接看update方法的JavaScript实现代码。 原文 http://www.cnblogs.com/stephen-liu74/archive/2012/08/08/2545998.html

mongodb 数据操作

1.  批量插入: 以数组的方式一次插入多个文档可以在单次TCP请求中完成,避免了多次请求中的额外开销。就数据传输量而言,批量插入的数据中仅包含一份消息头,而多次单条插入则会在每次插入数据时封装消息头数据。对于数据导入而言,我们可以使用mongoimport完成。 2.  数据库清除: > db.users.remove() 以上命令将会清除users集合中的所有数据,但是不会删除集合本身以及关联的索引。数据删除操作是不可恢复的,一旦删除就物理的删除了。对于全集合清除这种case,一个更为有效的方式是直接删除集合对象本身以及他关联的所有索引,之后再依次重建,如: > db.one_collection.drop() 3.  数据更新: 如果在执行数据更新时,有多条文档匹配更新条件,为了避免更新后的_id出现重复性冲突,MongoDB将仅更新第一条查询结果,如: > post1 = { "name": "stephen", "age" : "35"} { "name" : "stephen", "age" : "35" } > post2 = { "name": "stephen", "age" :  36} { "name" : "stephen", "age" : 36 } > db.blog.insert(post1) > db.blog.insert(post2) > post3 = { "name" : "stephen", "age": 37} { "name" : "stephen", "age" : 37 } > db.blog.update({"name":"stephen"},post3) > db.blog.find() { "_id" : ObjectId("4fcd7e2e20668578cc1097d8"), "name" : "stephen", "age" : 36 } { "_id" : ObjectId("4fcd7e2820668578cc1097d7"), "name" : "stephen", "age" : 37 } 4.  修改器: 使用修改器进行数据更新是原子的,也是高效的,不同于全部文档更新的是被更新文档的_id不会变化,而文档完全更新则会修改文档的_id,以及相关的索引。 > db.blog.find() { "_id" : ObjectId("4fcd7e2820668578cc1097d7"), "name" : "stephen", "age" : 41 } { "_id" : ObjectId("4fcd81bb20668578cc1097d9"), "name" : "stephen", "age" : 38 } --$inc修改符将匹配条件的文档的age键原子加一,缺省情况下只是更新第一条符合条件的文档。 > db.blog.update({"name":"stephen"},{"$inc":{"age":1}}) > db.blog.find() { "_id" : ObjectId("4fcd7e2820668578cc1097d7"), "name" : "stephen", "age" : 42 } { "_id" : ObjectId("4fcd81bb20668578cc1097d9"), "name" : "stephen", "age" : 38 } --可以通过update函数的最后一个参数来指定更新所有符合条件的文档,如: > db.blog.update({"name":"stephen"},{"$inc":{"age":1}},true,true) > db.blog.find() { "_id" : ObjectId("4fcd7e2820668578cc1097d7"), "name" : "stephen", "age" : 43 } { "_id" : ObjectId("4fcd81bb20668578cc1097d9"), "name" : "stephen", "age" : 39 } --$set修改符直接修改匹配文档的内容,如果修改的键存在则直接修改,否则新增。 > db.blog.update({"name":"stephen"},{"$set":{"genda":"male"}}) > db.blog.find() { "_id" : ObjectId("4fcd88b720668578cc1097da"), "age" : "35", "genda" : "male", "name" : "stephen" } --$unset修改符合$set的功能是完全相反的,如: > db.blog.update({"name":"stephen"},{"$unset":{"genda":"male"}}) > db.blog.find() { "_id" : ObjectId("4fcd88b720668578cc1097da"), "age" : "35", "name" : "stephen" } --可以通过$set修改符修改嵌套子文档。 > db.blog.find() { "_id" : ObjectId("4fcd8e0220668578cc1097db"), "title" : "A Blog Post", "author" : { "name" : "joe", "email" : "joe@ee.com" } } > db.blog.update({"title":"A Blog Post"},{"$set":{"author.name":"joe schmoe"}}) > db.blog.find() { "_id" : ObjectId("4fcd8e0220668578cc1097db"), "author" : { "email" : "joe@ee.com", "name" : "joe schmoe" }, "title" : "A Blog Post" } 5.  数组修改器: > db.blog.insert({"title":"one blog"}) > db.blog.find() { "_id" : ObjectId("4fcd909520668578cc1097dc"), "title" : "one blog" } --如果其操作的键不存在,则创建新的键值,其值的类型为数组类型。 > log.update({"title":"one blog"}, {"$push": {"comments":{"content":"hello"}}}) > db.blog.findOne() { "_id" : ObjectId("4fcd909520668578cc1097dc"), "comments" : [ { "content" : "hello" } ], "title" : "one blog" } --如果$push操作的键值已经存在,且其值为数组类型,该修改符将为该数组添加新的数组元素。 > db.blog.update({"title":"one blog"}, {"$push": {"comments":{"content":"word"}} > db.blog.findOne() { "_id" : ObjectId("4fcd909520668578cc1097dc"), "comments" : [ { "content" : "hello" }, { "content" : "word" } ], "title" : "one blog" } > post = {"username":"joe", "emails":["joe@example.com","joe@gmail.com","joe@yahoo.com"]} { "username" : "joe", "emails" : [ "joe@example.com", "joe@gmail.com", "joe@yahoo.com" ] } > db.blog.insert(post) > db.blog.findOne() { "_id" : ObjectId("4fd2e468b2ac404941134bed"), "username" : "joe", "emails" : [ "joe@example.com", "joe@gmail.com", "joe@yahoo.com" ] } --$addToSet适用于数组,如果数组中该元素已经存在,该命令就不做任何操作后返回,否则将新元素插入数组。 > db.blog.update({"username":"joe"}, {"$addToSet": {"emails":"joe@gmail.com"}}) > db.blog.findOne() { "_id" : ObjectId("4fd2e468b2ac404941134bed"), "username" : "joe", "emails" : [ "joe@example.com", "joe@gmail.com", "joe@yahoo.com" ] } > db.blog.update({"username":"joe"}, {"$addToSet": {"emails":"joe@hotmail.com"} > db.blog.findOne() { "_id" : ObjectId("4fd2e468b2ac404941134bed"), "emails" : [ "joe@example.com", "joe@gmail.com", "joe@yahoo.com", "joe@hotmail.com" ], "username" : "joe" } --$addToSet和$each的组合可以将数组插入到另外一个数组中。 > db.blog.update({"username":"joe"},{"$addToSet": {"emails":{"$each":["joe@php.net","joe@example.com"]}}}) > db.blog.findOne() { "_id" : ObjectId("4fd2e468b2ac404941134bed"), "emails" : [ "joe@example.com", "joe@gmail.com", "joe@yahoo.com", "joe@hotmail.com", "joe@php.net" ], "username" : "joe" } --$pop从数组中删除一个元素,如参数为1,表示从数组的尾部删除一个元素,如果是-1,则从头部删除。 > db.blog.update({"username":"joe"}, {"$pop":{"emails":1}}) > db.blog.findOne() { "_id" : ObjectId("4fd2e468b2ac404941134bed"), "emails" : [ "joe@example.com", "joe@gmail.com", "joe@yahoo.com", "joe@hotmail.com" ], "username" : "joe" } > db.blog.update({"username":"joe"}, {"$pop":{"emails":-1}}) > db.blog.findOne() { "_id" : ObjectId("4fd2e468b2ac404941134bed"), "emails" : [ "joe@gmail.com", "joe@yahoo.com", "joe@hotmail.com" ], "username" : "joe" } --$pull修改符则是从数据中删除指定的元素 > db.blog.update({"username":"joe"}, {"$pull":{"emails":"joe@yahoo.com"}}) > db.blog.findOne() { "_id" : ObjectId("4fd2e468b2ac404941134bed"), "emails" : [ "joe@gmail.com", "joe@hotmail.com" ], "username" : "joe" } --使数组中出现重复的元素,便于后面修改符的功能演示。 > db.blog.update({"username":"joe"}, {"$push": {"emails":"joe@gmail.com"}}) > db.blog.findOne() { "_id" : ObjectId("4fd2e468b2ac404941134bed"), "emails" : [ "joe@gmail.com", "joe@hotmail.com", "joe@gmail.com" ], "username" : "joe" } --在数组中,第一个元素的下标是0,然后依次增长。下面的示例是将数组中下标为1 --(第二个元素)的元素值修改为新值。 > db.blog.update({"username":"joe"}, {"$set":{"emails.1":"joe@example.com"}}) > db.blog.findOne() { "_id" : ObjectId("4fd2e468b2ac404941134bed"), "emails" : [ "joe@gmail.com", "joe@example.com", "joe@gmail.com" ], "username" : "joe" } --有的时候,特别是在修改查询结果的时候,我们无法获知结果文档数组下标,MongoDB --提供了$定位符表示查询结果的下标。但是该他只更新第一个匹配元素。 > db.blog.update({"emails":"joe@gmail.com"},{"$set":{"emails.$":"joe@hotmail.com"}}) > db.blog.findOne() { "_id" : ObjectId("4fd2e468b2ac404941134bed"), "emails" : [ "joe@hotmail.com", "joe@example.com", "joe@gmail.com" ], "username" : "joe" } 6.  upsert: upsert是一种特殊的更新。要是没有文档符合更新条件,就会以这个条件和更新文档为基础创建一个新的文档。如果找到了匹配的文档,则正常更新。 > db.blog.remove() > db.blog.update({"username":"joe"},{"username":"joe","age":30},true) > db.blog.findOne() { "_id" : ObjectId("4fd2faac576cd9c101ac0f3d"), "username" : "joe", "age" : 30 } 下面的示例可以在新增的同时,修改新增后的值。 > db.blog.remove() > db.blog.update({"count":25},{"$inc":{"count":3}},true) > db.blog.find() { "_id" : ObjectId("4fd2fd59576cd9c101ac0f3e"), "count" : 28 } save是一个shell函数,可以在文档不存在时插入,存在时更新。upsert也可以完成同样的工作,但是不如save命令方便。 > var x = db.blog.findOne() > x.count = 40 40 > db.blog.save(x) > db.blog.findOne() { "_id" : ObjectId("4fd2fde4576cd9c101ac0f3f"), "count" : 40 } 7.  返回已更新文档: 可以通过getLastError命令获取更新多个文档时被更新的文档数量。 > db.blog.remove() > db.blog.insert({"name":"stephen"}) > db.blog.insert({"name":"stephen3"}) > db.blog.insert({"name":"stephen4"}) > db.blog.update({},{"$set":{"name":"liu"}},false,true) --n:3表示修改的数量为3。 > db.runCommand({getLastError:1}) { "updatedExisting" : true, "n" : 3, "connectionId" : 1, "err" : null, "ok" : 1 } findAndModify可以原子性的修改查询结果,也可以原子性的删除查询结果。 > db.blog.insert({"name":"stephen"}) > db.blog.insert({"name":"stephen2"}) > db.blog.find() { "_id" : ObjectId("4fd30cd117f6dccb7c058244"), "name" : "stephen" } { "_id" : ObjectId("4fd30cd417f6dccb7c058245"), "name" : "stephen2" } > db.runCommand({"findAndModify":"blog", "query":{"name":"stephen2"},"update":{"$set":{"name":"stephen3"}}}) > db.blog.find() { "_id" : ObjectId("4fd30cd117f6dccb7c058244"), "name" : "stephen" } { "_id" : ObjectId("4fd30cd417f6dccb7c058245"), "name" : "stephen3" } > runCommand({"findAndModify":"blog", "query":{"name":"stephen3"},"remove":true}) > db.blog.find() { "_id" : ObjectId("4fd30cd117f6dccb7c058244"), "name" : "stephen" } findAndModify命令中每个键对应的值如下: findAndModify: 字符串类型的集合名称。 query:查询文档,用来检索文档的条件。 sort: 排序结果的条件。 update:修改文档,对所找到的文档执行的更新。 remove:布尔类型,表示是否删除文档。 new:布尔类型,表示返回的是更新前的文档还是更新后的文档。缺省是更新前文档。 update和remove必须有一个存在,也只能有一个存在。如果没有匹配的文档,该命令会返回一个错误。这个命令有些限制,即一次只能处理一个文档,也不能执行upsert操作,只能更新已有文档。 原文  http://www.cnblogs.com/stephen-liu74/archive/2012/08/06/2553737.html