mongodb简要教程
1.介绍
mongodb是面向文档的数据库。没有模式,文档的健不用事先定义。为大数据设计,考虑到扩展问题。
文档:mongodb中数据的基本单元。
集合:没有模式的表。
数据库:mongodb的单个实例。
每个文档都有一个特殊的键“_id”,它在文档所处的集合中是唯一的。
2.文档
多个键及其关联的值有序的放置在一起。
键名不能含\0,.,$,不能以_开头。
3.mongodb区分类型和大小写
4.集合
集合就是一组文档。集合是无模式的,意味着一个集合里面的文档可以是各种各样的。
为什么需要多个集合:
1.按照文档类型进行分类,提升内聚性,减少磁盘寻道操作。
2.提升查询速度。
3.使索引更有效果。
命名:
1.不能为空“”
2.不能含有\0
3.不能以system.开头
4.不能含有保留字符$
子集合
使用’.’字符分开的按命名空间划分的子集合。
数据库
每个数据库都有独立的访问权限,在磁盘上放置在不同的文件中。
命名规范
1.不能为空“”
2.不能含有空格,.,$,/,,\0
3.应该为全小写
4.最多64字节
5.不能取名为admin,local,config等
mongodb shell
shell是功能完备的javascript解释器。开启的时候会连到mongdb服务器的test数据库,并将这个数据库赋值给全局变量db。
使用数据库
use foobar
查看数据库
db
可以通过db变量来访问其中的集合
shell基本操作
1.创建
添加一个文档到集合里面
post = {‘title’:”my blog post”}
{ “title” : “my blog post” }db.blog.insert(post)
WriteResult({ “nInserted” : 1 })db.blog.find()
{ “_id” : ObjectId(“558ace91e553ee92857b8cef”), “title” : “my blog post” }
2.读取
db.blog.findOne()
{ “_id” : ObjectId(“558ace91e553ee92857b8cef”), “title” : “my blog post” }
3.更新
post
{ “title” : “my blog post” }
post.comments = []
[ ]
post
{ “title” : “my blog post”, “comments” : [ ] }
db.blog.update({‘title’:’my blog post’},post)
WriteResult({ “nMatched” : 1, “nUpserted” : 0, “nModified” : 1 })
db.blog.findOne()
{
“_id” : ObjectId(“558ace91e553ee92857b8cef”),
“title” : “my blog post”,
“comments” : [ ]
}
4.删除
db.blog.remove({‘title’:’my blog post’})
WriteResult({ “nRemoved” : 1 })db.blog.findOne()
null
5.删除集合
db.drop_collection(‘blog’)
5.使用shell的窍门
shell本身内置了帮助文档,可以通过help命令查看。
如果集合名与系统预留属性冲突会导致找不到属性。
可以使用db.getCollection(“version”)的方式来获取。
x.y,x[‘y’]完全等价
6.数据类型
1.基本数据类型
null:{‘x’:null}表示空值或者不存在的字段
bool:{‘x’:true}
32位整数:
64位整数:
64位浮点数:{‘x’:1.2}{‘y’:3}shell中的数字都是这种类型
字符串:{‘x’:’abc’}
对象id:{‘x’:ObjectId()}
日期:{“x”:new Date()} 从标准纪元开始的毫秒数
正则表达式:{‘x’:/foot/}
代码:javascript代码
二进制:
最大值:可能的最大值
最小值:表示可能的最小值
未定义:{‘x’:undefined}
数组:{‘x’:[1,2,3]}
内嵌文档:{‘x’:{‘a’:1}}
1.数字
默认情况下,shell中的数字都被mongodb当做双精度。
ObjectId使用12字节的存储空间,生成方式:
0-3 4-6 7-8 9-11
时间戳|机器|pid|计数器
计数器保证每个进程拥有最多1677万个不同的ObjectId
2.使用修改器
每次执行b自动累加,累加数为指定的大小,这里为10。
db.blog.update({‘a’:’1’},{“inc”:{‘b’:10}})
如果键不存在则创建,存在则更新。
db.blog.update({‘a’:’1’},{“set”:{‘c’:’c1’}})
去除键
db.blog.update({‘a’:’1’},{“unset”:{‘c’:’c1’}})
数组修改器
db.blog.update({‘a’:[1,2,3]},{“addToSet”:{‘a’:4}})
3.upset
先查找是否存在,不存在则创建,然后将修改器的文档应用于其上。
db.blog.update({‘a’:1},{“$inc”:{‘a’:1}},true)
4.同时更新多个文档
db.blog.update({‘a’:2},{“$inc”:{‘b’:10}},false,true)
第4个参数为false才会只更新一个。
5.解决并发问题
db.runCommand({‘findAndModify’:’blog’,’update’:{‘$set’:{‘c’:3}}.value})
6.瞬间完成
mongodb的插入、删除和更新都是瞬间完成的,不需要等待数据库响应。
7.请求和连接
mongodb为每一个数据库连接创建一个队列,保证能读取到自己写的数据。不同连接之间的数据是独立的。
8.查询
返回指定的键
db.blog.find({},{‘b’:0})
正则表达式
db.blog.find({‘a’:/[0-9]*/i})
查询内嵌文档
db.blog.find({‘e.e1’:’1’})
游标
var cursor = db.blog.find()
cursor.hasNext()
true
cursor.next()
{ “_id” : ObjectId(“558c252912712d216be45b3b”) }
cursor.next()
{ “_id” : ObjectId(“558c257212712d216be45b3e”), “a” : 2, “b” : 10 }
limit,skip,sort
db.blog.find().limit(2)
db.blog.find().skip(1)
db.blog.find().sort({‘b’:1})
索引
1.创建索引
db.people.ensureIndex({‘b’:1,’a’:-1})
db.people.ensureIndex({‘b’:1,’a’:-1},{‘background’,true})在后台创建索引,避免阻塞建立索引期间的所有请求。但是期间无法进行数据交互。
2.索引内嵌文档
db.people.ensureIndex({‘e.e1’:1})
3.索引名
db.people.ensureIndex({‘e.e1’:1},{‘name’:’index_b’})
4.唯一索引
db.people.ensureIndex({‘a’:1},{‘unique’:’true’})
db.people.ensureIndex({‘a’:1},{‘unique’:’true’,’dropDups’:true})创建唯一索引时去掉重复文档,只保留第一个。
5.使用explain和hint
explain用来查看是否使用索引,hint用来强制使用某个索引。
6.索引管理
索引元信息存储在每个数据库的system.indexes集合中。只能通过ensureIndex或者dropIndexes进行。
7删除索引
db.runCommand({‘dropIndexes’:’blog’,’index’:’index_1’})
聚合
1.count
返回集合中符合条件的文档数量
db.foo.count()
db.foo.count({‘x’:1})
2.distinct
找出给定键的所有不同的值。
db.runCommand({‘distinct’:’people’,’key’:’age’})
注意:只是获得指定键的不同值。
3.group
db.posts.group({
‘key’:{‘tags’:true},
‘initial’:{‘tags’:true},
‘reduce’:function(doc,prev){
for(i in doc.tags){
if(doc.tag[i] in prev.tags){
prev.tags[doc.tags[i]]++;
}
}
},
‘finalize’:function(prev){
delete prev.tags[0];
}
‘condition’:{‘day’:{‘$gt’:’2010/09/30’}}
})
key:指定分组的键
initial:为每组reduce函数初始化参数,创建一个累加器reduce:每个文档都会调用一次,参数为当前文档,累加器。
condition:只处理满足条件的文档。
finalize:每组结果返回到客户端前调用一次。
mapreduce
mr = db.runCommand({
‘mapreduce’:’foo’,
‘map’:function(..){…},
‘reduce’:function(…){…},
‘finalize’:function(…){…},
‘query’:{‘day’:{‘$gt’:’2010/09/30’}}
})
数据库命令
1.查看命令执行结果
db.runCommand({‘getLastError’:1})
2.返回集合统计信息,数据大小,已分配存储空间和索引大小
collStats
3.创建用户
db.addUser(‘u1’,’p1’)
db.addUser(‘u1’,’p1’,true) 只读账户