您的位置:首页 > 数据库 > Mongodb

就最近研究MongoDB,分享下常用的API。

2012-05-29 15:33 337 查看
最近在工作之余研究了下MongoDB,MongoDB是一种NoSQL型数据库,以集合和文档来描述数据并采用JSON的数据格式来描述。集合和文档分别相当于关系数据库中的表和记录概念。对于开发者而言,更多是关注Mongo shell的使用。Mongo shell是MongoDB的Client,Client采用javacript来访问和操作Server中的数据。Mongo shell 是一个很好的javascript引擎实现,完全实现了javascript的标准API,同时也为操作数据库扩展了一部分API(Mongo
shell内部函数),Mongo在启动后会去加载这些API,完成初始化,给用户脚本提供数据环境,这样开发人员的脚本中就可以访问Mongo shell内部函数。下面就简要地说说在学习过程中所了解的常用命令:

显示数据库

show dbs

创建数据库并选择创建的数据库(创建的数据库在插入了数据之后,此数据库才会被持久化)

use dbname

显示集合

show collections

$inc 追加

db.student.update({name:'aa'},{"$inc":{age:1}}) #给name为aa的文档age字段加1,如果是负数就是做减法

$set 修改字段值,字段不存在就新增字段。

db.student.update({name:"aa"},{"$set":{age:20}}})#将满足条件的文档的age设为20

$unset 删除键值

db.student.update({name:"aa"},{"$unset":{age:1}}})

$push 给数组字段(不存在此字段的话,就添加该字段)追加元素

db.student.update({name:"aa"},{"$push":{"emails":"ssss"}}})

$ne 用来查询不等条件,能用于所有数据类型。常和$push一起使用

db.student.update({"name":{"$ne":"aa"}},{"$inc":{age:1}}) #将名字为aa的文档age字段加1

$addToSet 用来向数组里追加记录(有相同的就不追加) 一般和$each使用,批量添加。

db.student.update({"name":'aa'},{"$addToSet":{"emails":'333'}})

$pop 从数组字段里删除一个元素

db.student.update({name:"aa"},{"$pop":{"emails":{"key":1}}}) #将email数组里删除一个元素,key是设置删除元素的位置,1为删除最后一个,-1为删除第一个

$in 在某个范围内的条件

db.student.find({age:{"$in":[18,29]}}) #查询年龄在[18,29]内的记录

$nin 不在指定范围内的条件

$gt 大于

$lt 小于

$gte 大于等于

$lte 小于等于

$or 或者条件

db.student.find({"$or":[{count:28},{date:2}]}) #查询满足{count:28}或者{date:2}的文档

$mod 取模运算

db.student.find({num:{$mod:[5,1]}}) #num%5 = 1的结果

$not 非条件 可用在其他条件之上

db.student.find({num:{$not:{$mod:[5,1]}}}) #num%5 != 1的结果

$exists 判定键值是否存在

db.student.find({z:{$in:[null],$exists:true}}) #查找含有z键,并且值为null的文档,如果不设置$exists的话,不含有z键的文档(当做null处理)也会查找

$all 判断查询的字段含有多个值的记录,用来查询数组字段。

db.student.insert({fruit:['apple','org','bab']})

db.student.find({fruit:{$all:['apple','org']}}) #查询fruit数组里含有apple和org的文档,和顺序无关。

db.student.find({fruit:'apple'}) 等价 db.student.find({fruit:{$all:['apple']}})

db.student.find({fruit:['apple']}) #这是完整匹配包括顺序

$size 查询指定长度数组

$slice 返回数组子集。相当于limit

db.student.find({name:'aa'},{comments:{$slice:10}}) #查询结果文档中comments数组内容只返回前10条记录。-10:返回后10条记录

$elemMatch 限定条件匹配。查询子文档时会用到。

getLastError命令,查询哪些文档更新。

findAndModify命令,查询哪些被更新的文档,用于分片群集环境中。

var obj = db.runCommand({

findAndModify:'processes', //集合名

query:{status:'READY'}, //查询文档的条件

sort:{priority:-1}, //排序结果的条件

update:{$set:{status:"RUNNING"}} //对找到的文档进行更新

remove:true对查询的条件文档做删除动作。

new:true表示返回的是更新后的文档,false表示返回的更新前的文档。

})

update({if},{replace},flag,mulit) //{if}:条件,replace:替换内容,flag:true-表示未找到就添加记录(根据条件和replace内容),mulit:true表示对满足条件的所有文档进行更新,false表示只更新第一条。批量更新的操作必须是在$操作符下才能工作。

db.student.remove() #删除集合中的所有文档,也可指定条件,满足条件的删掉。

条件句(查询器,条件句是作用内层文档的键,修改器是作用外层文档键),一个键可以有多个条件句,但不可以有多个修改器。

$where 几乎能做所有的查询。但由于要将BSON转成JSON,影响性能,建议不要过于使用。

db.student.find({$where:function() {return this.x==this.y}}) #方法返回true时该文档满足查询条件。this表示传进来的当前文档

$query 查询条件

db.student.find({name:11}) 发送到服务器时会将查询条件包装在一个大的文档中。被转成db.student.find({$query:{name:11}})

$orderby 排序条件 等同 游标的sort方法,执行sort方法会被转成这个操作符

db.student.find({name:11}).sort({name:-1}) 真正执行时被转成db.student.find({$query:{name:11},$orderby:{name:-1}})

$maxscan 设置最大扫描文档的个数

$min 查询的开始条件

$max 查询的结束条件

$hint 指定服务器使用哪个索引来查询

$explain:boolean 获取查询执行的细节(用到的索引、结果数量、耗时等),而并非真正执行查询

$snapshot:boolean 确保查询的结果是在查询执行那一刻的一致快照。

ensureIndex 方法

db.student.ensureIndex({name:1},{unique:true,dropDups:true}) 创建唯一索引,删除重复值的文档记录

explain 返回查询执行的细节

db.student.find().explain()

dropIndexes方法 删除索引

创建空间索引

db.student.ensureIndex({gps:"2d"}) gps键值必须是包含两个元素的数组或是包含两个键的内嵌文档默认情况下地理空间索引值的范围为-180~180之间,也可以用 ensureIndex的选项来指定最大最小值

db.student.ensureIndex({gps:"2d"},{min:-1000,max:1000})

地理空间查询有find或数据库命令等方式。

db.student.find({gps:{$near:[40,-73]}}) 查找(40,-73)点附近的节点

命令方式geoNear:

db.runCommand({geoNear:'student',near:[40,-73],num:10})

$box:矩形内查询

db.student.find({gps:{$within:{$box:[[10,20],[15,30]]}}}) 查找位于(10,20)左下角坐标,(15,30)右上角坐标,构成的矩形内的节点

$center:圆形内查询

db.student.find({gps:{$within:{$center:[[12,25],5]}}})

count 计算集合文档数

db.student.count()

distinct 返回集合中一个键的唯一值集合

db.find.distinct("count") 返回count字段所有唯一值。

db.runCommand({distinct:'student',key:'count'})

group 分组聚合

db.runCommand({group:{

ns:"stocks",//集合名

key:"day",//查找的键值

"initial":{time:0},//累加器初始值

"$reduce":function(doc,prev) { //doc:当前遍历文档,累加器计算的文档。每遍历一个文档就调用一次

if(doc.time>prev.time) {

prev.price = doc.price;

prev.time = doc.time;

}

} ,

condition:{day:{$gt:"2010/09/30"}},//设置查询条件,对满足条件的结果集合进行分组操作。

finalize:function(prev){ //对每个产生的结果进行处理,prev:累加器文档。能修改传递的参数,也能返回新值。

}

}})

等价

db.stocks.group({key:'day',initial:{time:0},"$reduce":function(doc,prev){},condition:{day:{"$gt":'2010/09/30'}}})

$keyf 将函数作为键值使用,和group组合应用,满足返回条件的会被当做相同的键值分组,mongodb和MongoDB同为一组可以用它进行复杂的分组操作

db.runCommand({group:{

ns:"ss",

"$keyf":function(x){ x:当前扫描的文档

return x.name.toLowerCase();

}

...

}

})

MapReduce 能做count、distinct、group所能做的事

map = function() { //创建map,利用系统emit函数给每个键(每扫描到一个键)创建文档{count:1},每次扫描的文档都会调用这个方法,this代表当前文档

for(var key in this) {

emit(key,{count:1})

}

}

reduce = function(key,emits) {//key:键,emits数组存放这个键对应创建的文档{count:1},map执行的结果产生的数据会传递到这里

total = 0

for(var i in emits) {

total += emits[i].count

}

return {count:total} //返回值的结构必须是能作为emits里的元素

}

//1.8版本以下,执行命令

mr = db.runCommand({"mapreduce":"student",map:map,reduce:reduce})

db.runCommand({

"mapreduce":"student",

"map":map,

"reduce":reduce,

"out":{replace:"mr",db:"test"},//指定结果的输出位置,指定这个就暗示keeptemp:true

"finalize": function(prev){},//对mapreduce结果进行处理,将结果存储在临时集合中。

"keeptemp":布尔,//连接关闭时,临时集合是否保存

"query":文档,//在发往map处理的文档前,先根据条件过滤文档

"sort":文档,//在发往map处理的文档前,先对文档进行排序(一般和limit使用)

"limit"数字n,//取查询结果的前n个文档发给map处理

"scope":文档,//javascript代码里可以访问的变量

"verbose":布尔//是否产生更加详细的日志

})

//1.8版本以上需要指出out输出,执行命令

db.student.mapReduce(map,reduce,{out:{replace:"mr",db:"test"}})

mongodb里的操作都被转成命令执行

db.mr.drop() 等价 db.runCommand({drop:'mr'}) 等价 db.$cmd.findOne({drop:'mr'})

查看系统支持的命令

db.listCommands()

常用命令

buildInfo

db.runCommand({buildInfo:1}) 查看服务器的版本和主机的操作系统

collStats 返回指定集合的统计信息:数据大小,已分配的存储空间,索引的大小。

db.runCommand({collStats:'student'})

distinct 返回集合中满足查询条件的文档的指定键的所有不同值

db.runCommand(distinct:'student',key:'keyname',query:query)

dropDatabase 删除当前数据库所有数据

db.runCommand({dropDatabase:1})

dropIndexes 删除指定集合的指定索引

db.runCommand({dropIndexes:'student',index:'indexname'}) index为'*'删除所有索引

isMaster 检查服务器是否是主服务器

db.runCommand({isMaster:1})

listDatabases 列出服务器上所有的数据库

db.runCommand({listDatabases:1})

ping 检查服务器连接是否正常,服务器上锁,也会相应。

db.runCommand({ping:1})

renameCollection 重命名集合 需要admin用户权限

db.runCommand({renameCollection:'a',to:'b'}) a,b必须是完整的命名空间

repairDatabase 修复并压缩数据库

serverStatus 返回服务器管理信息

创建固定大小的集合,环形队列存储

db.createCollection("student",{capped:true,size:100000,max:100})

convertToCapped 将普通集合转换成固定集合

db.runCommand({convertToCapped:'student',size:10000});

$natural 固定集合排序

system.js 集合里定义的全局变量,在所有地方都能访问。可以用来存储一些配置信息。

fs.chunks 集合里存放的是GridFS文件分片数据,GridFS是基于mongodb文档上的文件存储系统。

mongofiles put filename 上传文件到GridFS里,上传的文件会被分片存储在fs.chunks集合,fs.files集合里存储GridFS里的文件列表信息

mongofiles get filename 下载文件到本地文件系统

mongofiles delete filename 删除文件,同时会删除fs.chunks、fs.files

==============分布式部署

mongod --master 启动主服务器

mongod --slave --source ipaddress 启动从服务器

主从服务,从服务只提供查询功能,可以在从服务器的local.sources里追加主服务

副本集群,是只有一个是活动的,对外提供服务,其余的都是热备份服务。

作为片运行的是普通服务或副本集

分片部署

启动配置服务器 给路由服务器提供配置信息

mongod --dbpath path --port port

启动路由服务器 不做持久化

mongos --port port --configdb localhost:port 配置服务器地址端口

将普通db服务作为分片服务

在路由服务器执行addshard命令

db.runCommand({addshard:localhost:port,allowLocal:true}) 将指定的普通服务作为片
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: