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类似,只是可以删除一组符合条件的记录。 */ ?>

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

mongodb 查询

1.  基本查询: 构造查询数据。 > db.test.findOne() { "_id" : ObjectId("4fd58ecbb9ac507e96276f1a"), "name" : "stephen", "age" : 35, "genda" : "male", "email" : "stephen@hotmail.com" } --多条件查询。下面的示例等同于SQL语句的where name = "stephen" and age = 35 > db.test.find({"name":"stephen","age":35}) { "_id" : ObjectId("4fd58ecbb9ac507e96276f1a"), "name" : "stephen", "age" : 35, "genda" : "male", "email" : "stephen@hotmail.com" } --返回指定的文档键值对。下面的示例将只是返回name和age键值对。 > db.test.find({}, {"name":1,"age":1}) { "_id" : ObjectId("4fd58ecbb9ac507e96276f1a"), "name" : "stephen", "age" : 35 } --指定不返回的文档键值对。下面的示例将返回除name之外的所有键值对。 > db.test.find({}, {"name":0}) { "_id" : ObjectId("4fd58ecbb9ac507e96276f1a"), "age" : 35, "genda" : "male", "email" : "stephen@hotmail.com" } 2.  查询条件: MongoDB提供了一组比较操作符:$lt/$lte/$gt/$gte/$ne,依次等价于</<=/>/>=/!=。 --下面的示例返回符合条件age >= 18 && age <= 40的文档。 > db.test.find({"age":{"$gte":18, "$lte":40}}) { "_id" : ObjectId("4fd58ecbb9ac507e96276f1a"), "name" : "stephen", "age" : 35,"genda" : "male", "email" : "stephen@hotmail.com" } --下面的示例返回条件符合name != "stephen1" > db.test.find({"name":{"$ne":"stephen1"}}) { "_id" : ObjectId("4fd58ecbb9ac507e96276f1a"), "name" : "stephen", "age" : 35,"genda" : "male", "email" : "stephen@hotmail.com" } --$in等同于SQL中的in,下面的示例等同于SQL中的in ("stephen","stephen1") > db.test.find({"name":{"$in":["stephen","stephen1"]}}) { "_id" : ObjectId("4fd58ecbb9ac507e96276f1a"), "name" : "stephen", "age" : 35,"genda" : "male", "email" : "stephen@hotmail.com" } --和SQL不同的是,MongoDB的in list中的数据可以是不同类型。这种情况可用于不同类型的别名场景。 > db.test.find({"name":{"$in":["stephen",123]}}) { "_id" : ObjectId("4fd58ecbb9ac507e96276f1a"), "name" : "stephen", "age" : 35,"genda" : "male", "email" : "stephen@hotmail.com" } --$nin等同于SQL中的not in,同时也是$in的取反。如: > db.test.find({"name":{"$nin":["stephen2","stephen1"]}}) { "_id" : ObjectId("4fd58ecbb9ac507e96276f1a"), "name" : "stephen", "age" : 35,"genda" : "male", "email" : "stephen@hotmail.com" } --$or等同于SQL中的or,$or所针对的条件被放到一个数组中,每个数组元素表示or的一个条件。 --下面的示例等同于name = "stephen1" or age = 35 > db.test.find({"$or": [{"name":"stephen1"}, {"age":35}]}) { "_id" : ObjectId("4fd58ecbb9ac507e96276f1a"), "name" : "stephen", "age" : 35,"genda" : "male", "email" : "stephen@hotmail.com" } --下面的示例演示了如何混合使用$or和$in。 > db.test.find({"$or": [{"name":{"$in":["stephen","stephen1"]}}, {"age":36}]}) { "_id" : ObjectId("4fd58ecbb9ac507e96276f1a"), "name" : "stephen", "age" : 35,"genda" : "male", "email" : "stephen@hotmail.com" } --$not表示取反,等同于SQL中的not。 > db.test.find({"name": {"$not": {"$in":["stephen2","stephen1"]}}}) { "_id" : ObjectId("4fd58ecbb9ac507e96276f1a"), "name" : "stephen", "age" : 35,"genda" : "male", "email" : "stephen@hotmail.com" } 3.  null数据类型的查询: --在进行值为null数据的查询时,所有值为null,以及不包含指定键的文档均会被检索出来。 > db.test.find({"x":null}) { "_id" : ObjectId("4fd59d30b9ac507e96276f1b"), "x" : null } { "_id" : ObjectId("4fd59d49b9ac507e96276f1c"), "y" : 1 } --需要将null作为数组中的一个元素进行相等性判断,即便这个数组中只有一个元素。 --再有就是通过$exists判断指定键是否存在。 > db.test.find({"x": {"$in": [null], "$exists":true}}) { "_id" : ObjectId("4fd59d30b9ac507e96276f1b"), "x" : null } 4.  正则查询: --MongoDB中使用了Perl规则的正则语法。如: > db.test.find() { "_id" : ObjectId("4fd59ed7b9ac507e96276f1d"), "name" : "stephen" } { "_id" : ObjectId("4fd59edbb9ac507e96276f1e"), "name" : "stephen1" } --i表示忽略大小写 > db.test.find({"name":/stephen?/i}) { "_id" : ObjectId("4fd59ed7b9ac507e96276f1d"), "name" : "stephen" } { "_id" : ObjectId("4fd59edbb9ac507e96276f1e"), "name" : "stephen1" } 5.  数组数据查询: --基于数组的查找。 > db.test.find() { "_id" : ObjectId("4fd5a177b9ac507e96276f1f"), "fruit" : [ "apple", "banana", "peach" ] } { "_id" : ObjectId("4fd5a18cb9ac507e96276f20"), "fruit" : [ "apple", "kumquat","orange" ] } { "_id" : ObjectId("4fd5a1f0b9ac507e96276f21"), "fruit" : [ "cherry", "banana","apple" ] } --数组中所有包含banana的文档都会被检索出来。 > db.test.find({"fruit":"banana"}) { "_id" : ObjectId("4fd5a177b9ac507e96276f1f"), "fruit" : [ "apple", "banana", "peach" ] } { "_id" : ObjectId("4fd5a1f0b9ac507e96276f21"), "fruit" : [ "cherry", "banana","apple" ] } --检索数组中需要包含多个元素的情况,这里使用$all。下面的示例中,数组中必须同时包含apple和banana,但是他们的顺序无关紧要。 > db.test.find({"fruit": {"$all": ["banana","apple"]}}) { "_id" : ObjectId("4fd5a177b9ac507e96276f1f"), "fruit" : [ "apple", "banana", "peach" ] } { "_id" : ObjectId("4fd5a1f0b9ac507e96276f21"), "fruit" : [ "cherry", "banana", "apple" ] } --下面的示例表示精确匹配,即被检索出来的文档,fruit值中的数组数据必须和查询条件完全匹配,即不能多,也不能少,顺序也必须保持一致。 > db.test.find({"fruit":["apple","banana","peach"]}) { "_id" : ObjectId("4fd5a177b9ac507e96276f1f"), "fruit" : [ "apple", "banana", peach" ] } --下面的示例将匹配数组中指定下标元素的值。数组的起始下标是0。 > db.test.find({"fruit.2":"peach"}) { "_id" : ObjectId("4fd5a177b9ac507e96276f1f"), "fruit" : [ "apple", "banana", peach" ] } --可以通过$size获取数组的长度,但是$size不能和比较操作符联合使用。 > db.test.find({"fruit": {$size : 3}}) { "_id" : ObjectId("4fd5a177b9ac507e96276f1f"), "fruit" : [ "apple", "banana", "peach" ] } { "_id" : ObjectId("4fd5a18cb9ac507e96276f20"), "fruit" : [ "apple", "kumquat","orange" ] } { "_id" : ObjectId("4fd5a1f0b9ac507e96276f21"), "fruit" : [ "cherry", "banana","apple" ] } --如果需要检索size > n的结果,不能直接使用$size,只能是添加一个额外的键表示数据中的元素数据,在操作数据中的元素时,需要同时更新size键的值。 --为后面的实验构造数据。 > db.test.update({}, {"$set": {"size":3}},false,true) > db.test.find() { "_id" : ObjectId("4fd5a18cb9ac507e96276f20"), "fruit" : [ "apple", "kumquat", "orange" ], "size" : 3 } { "_id" : ObjectId("4fd5a1f0b9ac507e96276f21"), "fruit" : [ "cherry", "banana", "apple" ], "size" : 3 } --每次添加一个新元素,都要原子性的自增size一次。 > test.update({},{"$push": {"fruit":"strawberry"},"$inc":{"size":1}},false,true) > db.test.find() { "_id" : ObjectId("4fd5a18cb9ac507e96276f20"), "fruit" : [ "apple", "kumquat", "orange", "strawberry" ], "size" : 4 } { "_id" : ObjectId("4fd5a1f0b9ac507e96276f21"), "fruit" : [ "cherry", "banana", "apple", "strawberry" ], "size" : 4 } --通过$slice返回数组中的部分数据。"$slice":2表示数组中的前两个元素。 > db.test.find({},{"fruit": {"$slice":2}, "size":0}) { "_id" : ObjectId("4fd5a18cb9ac507e96276f20"), "fruit" : [ "apple", "kumquat" ]} { "_id" : ObjectId("4fd5a1f0b9ac507e96276f21"), "fruit" : [ "cherry", "banana" ]} --通过$slice返回数组中的部分数据。"$slice":-2表示数组中的后两个元素。 > db.test.find({},{"fruit": {"$slice":-2}, "size":0}) { "_id" : ObjectId("4fd5a18cb9ac507e96276f20"), "fruit" : [ "orange", "strawberry" ] } { "_id" : ObjectId("4fd5a1f0b9ac507e96276f21"), "fruit" : [ "apple", "strawberry" ] } --$slice : [2,1],表示从第二个2元素开始取1个,如果获取数量大于2后面的元素数量,则取后面的全部数据。 > db.test.find({},{"fruit": {"$slice":[2,1]}, "size":0}) { "_id" : ObjectId("4fd5a18cb9ac507e96276f20"), "fruit" : [ "orange" ] } { "_id" : ObjectId("4fd5a1f0b9ac507e96276f21"), "fruit" : [ "apple" ] } 6.  内嵌文档查询: --为后面的示例构造测试数据。 > db.test.find() { "_id" : ObjectId("4fd5ada3b9ac507e96276f22"), "name" : { "first" : "Joe", "last" : "He" }, "age" : 45 }  --当嵌入式文档为数组时,需要$elemMatch操作符来帮助定位某一个元素匹配的情况,否则嵌入式文件将进行全部的匹配。 --即检索时需要将所有元素都列出来作为查询条件方可。 > db.test.findOne() { "_id" : ObjectId("4fd5af76b9ac507e96276f23"), "comments" : [ { "author" : "joe", "score" : 3 }, { "author" : "mary", "score" : 6 } ] } > db.test.find({"comments": {"$elemMatch": {"author":"joe","score":{"$gte":3}}}} { "_id" : ObjectId("4fd5af76b9ac507e96276f23"), "comments" : [ { "author" : "joe", "score" : 3 }, { "author" : "mary", "score" : 6 } ] } 7.  游标: 数据库使用游标来返回find()的执行结果,客户端对游标可以进行有效的控制,如:限定结果集的数量、跳过部分结果、基于任意键的任意方向的排序等。 下面的例子将用于准备测试数据。 > db.testtable.remove() > for (i = 0; i < 10; ++i) { ... db.testtable.insert({x:i}) ... } 我们可以通过cursor提供的hasNext()方法判断是否还有未读取的数据,再通过next()方法读取结果集中的下一个文档。如: > var c = db.testtable.find() > while (c.hasNext()) { ... print(c.next().x) ... } 0 1 2 3 4 5 6 7 8 9 当调用find()的时候,shell并不立即查询数据库,而是等待真正开始要求获得结果的时候才发送查询,这样在执行之前可以给查询附加额外的选项。几乎所有的游标方法都返回本身,因此可以像下面这样将游标的方法链式组合起来。如: > var c1 = db.testtable.find().sort({"x":1}).limit(1).skip(4); > var c2 = db.testtable.find().limit(1).sort({"x":1}).skip(4); > var c3 = db.testtable.find().skip(4).limit(1).sort({"x":1}); 此时,查询并未执行,所有这些函数都是在构造查询,当执行下面的语句时,查询将被真正执行, > c.hasNext() 查询被发送到服务器,MongoDB服务器每次将返回一批数据,当本批被全部迭代后再从服务器读取下一批数据,直至查询结果需要的数据被全部迭代。 对于上面的示例,limit(1)表示输出结果仅为一个,如果小于1,则不输出,即limit(n)函数限定的是最多输出结果。skip(4)表示跳过查询结果中的前4个文档,如果结果小于4,则不会返回任何文档。sort({"x":1})用于设定排序条件,即按照x键以升序(1)的方式排序,如果需要降序排序可以改为:sort({"x":-1})。sort也可以支持多键排序,如:sort({username:1, age:-1})即先按照username进行升序排序,如果username的值相同,再以age键进行降序排序。这里需要指出的是,如果skip过多的文档,将会导致性能问题。 原文 http://www.cnblogs.com/stephen-liu74/archive/2012/08/03/2553803.html

mongodb 索引

一、索引基础: MongoDB的索引几乎与传统的关系型数据库一模一样,这其中也包括一些基本的优化技巧。下面是创建索引的命令: > db.test.ensureIndex({"username":1}) 可以通过下面的名称查看索引是否已经成功建立: > db.test.getIndexes() 删除索引的命令是: > db.test.dropIndex({"username":1}) 在MongoDB中,我们同样可以创建复合索引,如: -- 数字1表示username键的索引按升序存储,-1表示age键的索引按照降序方式存储。 > db.test.ensureIndex({"username":1, "age":-1}) 该索引被创建后,基于username和age的查询将会用到该索引,或者是基于username的查询也会用到该索引,但是只是基于age的查询将不会用到该复合索引。因此可以说,如果想用到复合索引,必须在查询条件中包含复合索引中的前N个索引列。然而如果查询条件中的键值顺序和复合索引中的创建顺序不一致的话,MongoDB可以智能的帮助我们调整该顺序,以便使复合索引可以为查询所用。如: > db.test.find({"age": 30, "username": "stephen"}) 对于上面示例中的查询条件,MongoDB在检索之前将会动态的调整查询条件文档的顺序,以使该查询可以用到刚刚创建的复合索引。 我们可以为内嵌文档创建索引,其规则和普通文档没有任何差别,如: > db.test.ensureIndex({"comments.date":1}) 对于上面创建的索引,MongoDB都会根据索引的keyname和索引方向为新创建的索引自动分配一个索引名,下面的命令可以在创建索引时为其指定索引名,如: > db.test.ensureIndex({"username":1},{"name":"testindex"}) 随着集合的增长,需要针对查询中大量的排序做索引。如果没有对索引的键调用sort,MongoDB需要将所有数据提取到内存并排序。因此在做无索引排序时,如果数据量过大以致无法在内存中进行排序,此时MongoDB将会报错。 二、唯一索引: 在缺省情况下创建的索引均不是唯一索引。下面的示例将创建唯一索引,如: > db.test.ensureIndex({"userid":1},{"unique":true}) 如果再次插入userid重复的文档时,MongoDB将报错,以提示插入重复键,如: > db.test.insert({"userid":5}) > db.test.insert({"userid":5}) E11000 duplicate key error index: test.test.$userid_1  dup key: { : 5.0 } 如果插入的文档中不包含userid键,那么该文档中该键的值为null,如果多次插入类似的文档,MongoDB将会报出同样的错误,如: > db.test.insert({"userid1":5}) > db.test.insert({"userid1":5}) E11000 duplicate key error index: test.test.$userid_1  dup key: { : null } 如果在创建唯一索引时已经存在了重复项,我们可以通过下面的命令帮助我们在创建唯一索引时消除重复文档,仅保留发现的第一个文档,如: --先删除刚刚创建的唯一索引。 > db.test.dropIndex({"userid":1}) --插入测试数据,以保证集合中有重复键存在。 > db.test.remove() > db.test.insert({"userid":5}) > db.test.insert({"userid":5}) --创建唯一索引,并消除重复数据。 > db.test.ensureIndex({"userid":1},{"unique":true,"dropDups":true}) --查询结果确认,重复的键确实在创建索引时已经被删除。 > db.test.find() { "_id" : ObjectId("4fe823c180144abd15acd52e"), "userid" : 5 } 我们同样可以创建复合唯一索引,即保证复合键值唯一即可。如: > db.test.ensureIndex({"userid":1,"age":1},{"unique":true}) 三、使用explain: explain是非常有用的工具,会帮助你获得查询方面诸多有用的信息。只要对游标调用该方法,就可以得到查询细节。explain会返回一个文档,而不是游标本身。如: > db.test.find().explain() { "cursor" : "BasicCursor", "nscanned" : 1, "nscannedObjects" : 1, "n" : 1, "millis" : 0, "nYields" : 0, "nChunkSkips" : 0, "isMultiKey" : false, "indexOnly" : false, "indexBounds" : { } } explain会返回查询使用的索引情况,耗时和扫描文档数的统计信息。     "cursor":"BasicCursor"表示没有使用索引。     "nscanned":1 表示查询了多少个文档。     "n":1 表示返回的文档数量。     "millis":0 表示整个查询的耗时。 四、索引管理: system.indexes集合中包含了每个索引的详细信息,因此可以通过下面的命令查询已经存在的索引,如: > db.system.indexes.find() 如果在为已有数据的文档创建索引时,可以执行下面的命令,以使MongoDB在后台创建索引,这样的创建时就不会阻塞其他操作。但是相比而言,以阻塞方式创建索引,会使整个创建过程效率更高,但是在创建时MongoDB将无法接收其他的操作。 > db.test.ensureIndex({"username":1},{"background":true})

linux Mongodb 安装及使用

mongodb由C++写就,其名字来自humongous这个单词的中间部分,从名字可见其野心所在就是海量数据的处理。关于它的一个最简洁描述为:scalable, high-performance, open source, schema-free, document-oriented database。MongoDB的主要目标是在键/值存储方式(提供了高性能和高度伸缩性)以及传统的RDBMS系统(丰富的功能)架起一座桥梁,集两者的优势于一身。 安装及使用: 首先在Ubuntu上安装MongoDB。 下载MongoDB, 现在最新的生产版本1.7.0 1.                   解压文件. $ tar -xvf mongodb-linux-i686-1.4.3.tgz 2.                  为MongoDB创建数据目录,默认情况下它将数据存储在/data/db $ sudo mkdir -p /data/db/ $ sudo chown `id -u` /data/db 3.                  启动MongoDB服务. $ cd mongodb-linux-i686-1.4.3/bin $ ./mongod 4.                  打开另一个终端,并确保你在MongoDB的bin目录,输入如下命令. $ ./mongo 一些概念 一个mongod服务可以有建立多个数据库,每个数据库可以有多张表,这里的表名叫collection,每个collection可以存放多个文档(document),每个文档都以BSON(binary json)的形式存放于硬盘中,因此可以存储比较复杂的数据类型。它是以单文档为单位存储的,你可以任意给一个或一批文档新增或删除字段,而不会对其它文档造成影响,这就是所谓的schema-free,这也是文档型数据库最主要的优点。跟一般的key-value数据库不一样的是,它的value中存储了结构信息,所以你又可以像关系型数据库那样对某些域进行读写、统计等操作。Mongo最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。Mongo还可以解决海量数据的查询效率,根据官方文档,当数据量达到50GB以上数据时,Mongo数据库访问速度是MySQL10 倍以上。 BSON BSON是Binary JSON 的简称,是一个JSON文档对象的二进制编码格式。BSON同JSON一样支持往其它文档对象和数组中再插入文档对象和数组,同时扩展了JSON的数据类型。如:BSON有Date类型和BinDate类型。 BSON被比作二进制的交换格式,如同Protocol Buffers,但BSON比它更“schema-less”,非常好的灵活性但空间占用稍微大一点。 BSON有以下三个特点: 1.  轻量级 2.  跨平台 3.  效率高 命名空间 MongoDB存储BSON对象到collections,这一系列的数据库名和collection名被称为一个命名空间。如同:java.util.List;用来管理数据库中的数据。 索引 mongodb可以对某个字段建立索引,可以建立组合索引、唯一索引,也可以删除索引,建立索引就意味着增加空间开销。默认情况下每个表都会有一个唯一索引:_id,如果插入数据时没有指定_id,服务会自动生成一个_id,为了充分利用已有索引,减少空间开销,最好是自己指定一个unique的key为_id,通常用对象的ID比较合适,比如商品的ID。 shell操作数据库: 1.  超级用户相关: 1. #进入数据库admin use admin 2. #增加或修改用户密码 db.addUser('name','pwd') 3. #查看用户列表 db.system.users.find() 4. #用户认证 db.auth('name','pwd') 5. #删除用户 db.removeUser('name') 6. #查看所有用户 show users 7. #查看所有数据库 show dbs 8. #查看所有的collection show collections 9. #查看各collection的状态 db.printCollectionStats() 10. #查看主从复制状态 db.printReplicationInfo() 11. #修复数据库 db.repairDatabase() 12. #设置记录profiling,0=off 1=slow 2=all db.setProfilingLevel(1) 13. #查看profiling show profile 14. #拷贝数据库 db.copyDatabase('mail_addr','mail_addr_tmp') 15. #删除collection db.mail_addr.drop() 16. #删除当前的数据库 db.dropDatabase() 2. 增删改 1. #存储嵌套的对象 db.foo.save({'name':'ysz','address':{'city':'beijing','post':100096},'phone':[138,139]}) 2. #存储数组对象 db.user_addr.save({'Uid':'yushunzhi@sohu.com','Al':['test-1@sohu.com','test-2@sohu.com']}) 3. #根据query条件修改,如果不存在则插入,允许修改多条记录 db.foo.update({'yy':5},{'$set':{'xx':2}},upsert=true,multi=true) 4. #删除yy=5的记录 db.foo.remove({'yy':5}) 5. #删除所有的记录 db.foo.remove() 3. 索引 1. #增加索引:1(ascending),-1(descending) 2. db.foo.ensureIndex({firstname: 1, lastname: 1}, {unique: true}); 3. #索引子对象 4. db.user_addr.ensureIndex({'Al.Em': 1}) 5. #查看索引信息 6. db.foo.getIndexes() 7. db.foo.getIndexKeys() 8. #根据索引名删除索引 9. db.user_addr.dropIndex('Al.Em_1') 4. 查询 1. #查找所有 2. db.foo.find() 3. #查找一条记录 4. db.foo.findOne() 5. #根据条件检索10条记录 6. db.foo.find({'msg':'Hello 1'}).limit(10) 7. #sort排序 8. db.deliver_status.find({'From':'ixigua@sina.com'}).sort({'Dt',-1}) 9. db.deliver_status.find().sort({'Ct':-1}).limit(1) 10. #count操作 11. db.user_addr.count() 12. #distinct操作,查询指定列,去重复 13. db.foo.distinct('msg') 14. #”>=”操作 15. db.foo.find({"timestamp": {"$gte" : 2}}) 16. #子对象的查找 17. db.foo.find({'address.city':'beijing'}) 5. 管理 1. #查看collection数据的大小 2. db.deliver_status.dataSize() 3. #查看colleciont状态 4. db.deliver_status.stats() 5. #查询所有索引的大小 6. db.deliver_status.totalIndexSize() 5.  advanced queries:高级查询 条件操作符 $gt : > $lt : < $gte: >= $lte: <= $ne : !=、<> $in : in $nin: not in $all: all $not: 反匹配(1.3.3及以上版本) 查询 name <> "bruce" and age >= 18 的数据 db.users.find({name: {$ne: "bruce"}, age: {$gte: 18}}); 查询 creation_date > '2010-01-01' and creation_date <= '2010-12-31' 的数据 db.users.find({creation_date:{$gt:new Date(2010,0,1), $lte:new Date(2010,11,31)}); 查询 age in (20,22,24,26) 的数据 db.users.find({age: {$in: [20,22,24,26]}}); 查询 age取模10等于0 的数据 db.users.find('this.age % 10 == 0'); 或者 db.users.find({age : {$mod : [10, 0]}}); 匹配所有 db.users.find({favorite_number : {$all : [6, 8]}}); 可以查询出{name: 'David', age: 26, favorite_number: [ 6, 8, 9 ] } 可以不查询出{name: 'David', age: 26, favorite_number: [ 6, 7, 9 ] } 查询不匹配name=B*带头的记录 db.users.find({name: {$not: /^B.*/}}); 查询 age取模10不等于0 的数据 db.users.find({age : {$not: {$mod : [10, 0]}}}); #返回部分字段 选择返回age和_id字段(_id字段总是会被返回) db.users.find({}, {age:1}); db.users.find({}, {age:3}); db.users.find({}, {age:true}); db.users.find({ name : "bruce" }, {age:1}); 0为false, 非0为true 选择返回age、address和_id字段 db.users.find({ name : "bruce" }, {age:1, address:1}); 排除返回age、address和_id字段 db.users.find({}, {age:0, address:false}); db.users.find({ name : "bruce" }, {age:0, address:false}); 数组元素个数判断 对于{name: 'David', age: 26, favorite_number: [ 6, 7, 9 ] }记录 匹配db.users.find({favorite_number: {$size: 3}}); 不匹配db.users.find({favorite_number: {$size: 2}}); $exists判断字段是否存在 查询所有存在name字段的记录 db.users.find({name: {$exists: true}}); 查询所有不存在phone字段的记录 db.users.find({phone: {$exists: false}}); $type判断字段类型 查询所有name字段是字符类型的 db.users.find({name: {$type: 2}}); 查询所有age字段是整型的 db.users.find({age: {$type: 16}}); 对于字符字段,可以使用正则表达式 查询以字母b或者B带头的所有记录 db.users.find({name: /^b.*/i}); $elemMatch(1.3.1及以上版本) 为数组的字段中匹配其中某个元素 Javascript查询和$where查询 查询 age > 18 的记录,以下查询都一样 db.users.find({age: {$gt: 18}}); db.users.find({$where: "this.age > 18"}); db.users.find("this.age > 18"); f = function() {return this.age > 18} db.users.find(f); 排序sort() 以年龄升序asc db.users.find().sort({age: 1}); 以年龄降序desc db.users.find().sort({age: -1}); 限制返回记录数量limit() 返回5条记录 db.users.find().limit(5); 返回3条记录并打印信息 db.users.find().limit(3).forEach(function(user) {print('my age is ' + user.age)}); 结果 my age is 18 my age is 19 my age is 20 限制返回记录的开始点skip() 从第3条记录开始,返回5条记录(limit 3, 5) db.users.find().skip(3).limit(5); 查询记录条数count() db.users.find().count(); db.users.find({age:18}).count(); 以下返回的不是5,而是user表中所有的记录数量 db.users.find().skip(10).limit(5).count(); 如果要返回限制之后的记录数量,要使用count(true)或者count(非0) db.users.find().skip(10).limit(5).count(true); 分组group() 假设test表只有以下一条数据 { domain: "www.mongodb.org" , invoked_at: {d:"2009-11-03", t:"17:14:05"} , response_time: 0.05 , http_action: "GET /display/DOCS/Aggregation" } 使用group统计test表11月份的数据count:count(*)、total_time:sum(response_time)、avg_time:total_time/count; db.test.group( { cond: {"invoked_at.d": {$gt: "2009-11", $lt: "2009-12"}} , key: {http_action: true} , initial: {count: 0, total_time:0} , reduce: function(doc, out){ out.count++; out.total_time+=doc.response_time } , finalize: function(out){ out.avg_time = out.total_time / out.count } } ); [ { "http_action" : "GET /display/DOCS/Aggregation", "count" : 1, "total_time" : 0.05, "avg_time" : 0.05 } ] Java 应用示例 要使用Java操作MongoDB的话,要到官方网站下载一个驱动包,把包导入后,可以尝试来操作了(记得一定要开着服务器) 首先介绍一下比较常用的几个类 Mongo:连接服务器,执行一些数据库操作的选项,如新建立一个数据库等 DB:对应一个数据库,可以用来建立集合等操作 DBCollection:对应一个集合(类似表),可能是我们用得最多的,可以添加删除记录等 DBObjec:接口和BasicDBObject对象:表示一个具体的记录,BasicDBObject实现了DBObject,因为是key-value的数据结构,所以用起来其实和HashMap是基本一致的 DBCursor:用来遍历取得的数据,实现了Iterable和Iterator 接下来实际的操作一下,代码如下: import java.net.UnknownHostException; import java.util.List; import java.util.Set; import com.mongodb.BasicDBObject; import com.mongodb.DB; import com.mongodb.DBCollection; import com.mongodb.DBCursor; import com.mongodb.DBObject; import com.mongodb.Mongo; import com.mongodb.MongoException; public class MongoDbTest { public static void main(String[] args) throws UnknownHostException, MongoException { //Mongo m = new Mongo(); //Mongo m = new Mongo("localhost"); //获得数据库服务 Mongo m = new Mongo("localhost", 27017); //得到数据库mytest DB db = m.getDB("mytest"); //得到mytest数据库下所有表名 Set<String> colls = db.getCollectionNames(); for (String s : colls) { System.out.println(s); } //得到testCollection表 DBCollection coll = db.getCollection("testCollection"); //new 一个BasicDBObject对象doc BasicDBObject doc = new BasicDBObject(); //赋值 doc.put("name", "MongoDB"); doc.put("type", "database"); doc.put("count", 1); //又new 一个BasicDBObject对象info BasicDBObject info = new BasicDBObject(); info.put("x", 203); info.put("y", 102); //把info放入doc doc.put("info", info); //向testCollection表中插入一条数据 coll.insert(doc); //查询一条数据 DBObject myDoc = coll.findOne(); System.out.println(myDoc); //循环插入100条数据到testCollection for (int i=0; i < 100; i++) { coll.insert(new BasicDBObject().append("i", i)); } //Counting Documents in A Collection System.out.println(coll.getCount()); //Using a Cursor to Get All the Documents DBCursor cur = coll.find(); while(cur.hasNext()) {   原文地址 : http://blog.163.com/venus_ke/blog/static/175484399201010895652190/