MongoDB是面向文档的数据库。

索引:MongoDB支持通用辅助索引,能进行多种快速查询,也提供唯一的、复合的和地理空间索引能力。

存储JavaScript:开发人员不必使用存储过程了,可以直接在服务端存取JavaScript的函数和值。

聚合:MongoDB支持MapReduce和其他聚合工具。

固定集合:集合的大小是有上限的,这对某些数据类型的数据特别有用(日志)。

文件存储:MongoDB支持用一种容易使用的协议存储大型文件和文件的元数据。

MongoDB使用MongoDB传输协议作为与服务器交互的主要方式。它对文档进行动态填充,预分配数据文件,用空间换取性能的稳定。默认的存储引擎中使用了内存映射文件,将内存管理工作交给操作系统去处理。动态查询优化器会“记住”执行查询最高效的方式。

文档是MongoDB的核心概念。多个键及其管理的值有序地放置在一起便是文档。文档中的键/值是有序的。文档的键使用任意UTF-8字符。键不能含有\0(空字符),这个字符用来表示键的结尾;.和$是被保留字,不可以使用;以下划线“_”开头的键是保留的。

集合是一组文档。集合是无模式的。集合的命名:集合名不可以是空字符串"";集合名不能含有\0;集合名不能以"system."开头,这是为系统集合保留的前缀;用户创建的集合名子不能含有保留字符$。

组织集合的一种惯例是使用"."字符分开的按命名空间划分的子集合。

数据库最终会变成文件系统中的文件,因此数据库名要满足不能是空字符串;不能还有""、.、/、\和\0;应全部小写;最多64字节。

保留的数据库: 
admin:从权限的角度来看,这是"root"数据库。若将一个用户添加到这个数据库,这个用户自动继承所有数据库的权限。 
local:这个数据库永远不会被复制,可以用来存储限于本地单台服务器的任意集合。 
config:当Mongo用于分片设置时,config数据库在内部使用,用于保存分片的相关信息。

MongoDB自带一个JavaScript shell,可以从命令行与MongoDB实例交互。可以通过shell执行管理操作、检查运行实例等。shell会在启动时自动连接MongoDB服务器。shell是功能完备的JavaScript解析器,可以运行任何JavaScript程序。

在shell查看操作数据会用到4个基本操作:创建、读取、更新和删除。 
创建(insert): 
>post = {"title" : "my blog", ... "content" : "Here is my blog", ... "data" : new Date() } 

          "title" : "My Blog" , 
          "content" : "Here is my blog" , 
          "data" : "       "         
}  
db.blog.insert(post)

查找:db.blog.find(){} 
     db.blog.findOne(){} 
find和findOne可以接受查询文档形式的限定条件。使用find时,shell自动显示最多20个匹配文档,但可以获取更多的文档。

更新:update接受至少2个参数:第一个是要更新文档的限定条件;第二个是新的文档。 
post.comments=[] 
db.blog.update({title:"My Blog"},post)

删除:remove用来从数据库中永久性的删除文档。在不使用参数进行调用的情况下,它会删除一个集合内的所有文档。 
db.blog.remove({title:"My Blog"})

当属性与集合同名时,可以使用getCollection函数。若要查看名称中含有无效JavaScript字符的集合,也可使用getCollection函数。

MongoDB在保留JSON(null、布尔、数字、字符串、数组和对象)基本的键/值对特性的基础上,添加了其他一些数据类型(32位整数、64位整数、64位浮点数、对象id、日期、正则表达式、代码)。

MongoDB数字只能表示为双精度,因此尽量不要在shell下覆盖整个文档,并且有些64位的整数并能精确地表示为64位浮点数,所以若是存入了一个64位整数,然后在shell中查看它,它会显示一个内嵌文档,但表示可能不准。要插入的64位整数不能精确地作为双精度数显示,shell会添加两个键:"top"和"bottom",分别表示高32位和低32位。

数组是一组值,既可以作为有序对象来操作,也可作为无序对象操作。数组可以包含不同数据类型的元素,甚至是嵌套数组。

内嵌文档就是把整个MongoDB文档作为另一个文档中键的值。

MongoDB中存储的文档必须有一个"_id"键。这个键值可以是任何类型的,默认的是ObjectId对象。在一个集合里面,每个文档都有唯一的"_id"值来确保集合里面每个文档都能被唯一标识。

ObjectId是"_id"的默认类型。它设计成轻量型的,不同的机器都能用全局唯一的同种方法方便地生成它。ObjectId使用12字节的存储空间,每个字节两位16进制数字,是一个24位的字符串。ObjectId的创建方式: 
   0|1|2|3|4|5|6|7|8|9|10|11 
   时间戳 |机器 |PID| 计数器 
前4个字节是从标准纪元开始的时间戳,单位为秒;随后的5个字节组合起来提供了秒级别的唯一性;后3个字节是一个自动增加的计数器,确保同一秒产生的ObjectId是不同的。同一秒最多允许每个进程拥有256^3个不同的ObjectId。

当执行插入操作的时候,使用的驱动程序会将数据转换成BSON的形式,然后将其送入数据库。数据库解析BSON,检验是否包含"_id"键并且文档不超过4MB,除此之外,不做别的数据验证,就只简单地将文档原样存入数据库中。

删除数据是永远的,不能撤销也不能恢复。删除文档通常会很快,但要清楚整个集合会更快。

更新操作是原子的:若要两个更新同时发生先到达服务器的先执行,接着执行另一个,所有冲突的更新都不互相干扰,最后个更新会取得胜利。

当模式结构发生了较大变化时,用一个较新的文档代替匹配的文档比较好;当文档只有部分要更新,利用原子的更新修改器性能会很高效。更新修改器是一种特殊的键。

修改器: 
$set用来指定一个键的值。若这个键不存在,则创建它。 
db.users.findOne(){ 
   "_id" : ObjectId(1), 
   "name" : "joe", 
   "age" : 30 

db.users.update({"_id" : ObjectId(1)},{"$set" : {"sex" : "male" }}) 
db.users.update({"_id" : ObjectId(1)},{"$set":{"favorite books": ["war and peace","cat's cradle","foundation trilogy"]}}) 
db.users.update({"name" : "joe",{"favorite books" :1}})

$inc用来增加已有的键的值,或在键不存在时创建一个键。只能用于整数、长整数或双精度浮点数。 
db.games.update({"game" : "pinball","user" : "joe"},{"$inc":{"score : 50"}})

$push会向已有的数组末尾加入一个元素,要是没有则新建一个数组。 
db.blog.update({"title" : "A blog",{$push : {"comments" : {"name":"joe","email" : "123@123.com","content" :"nice blog"}}}) 
db.blog.update({"title" : "A blog",{$push : {"comments" : [{"name":"joe1","email" : "1123@123.com","content" :"nice blog1"},{"name":"joe2","email" : "2123@123.com","content" :"nice blog2"}]}})

$ne可以查询文档。 
db.papers.update({"authors cited" : {"$ne" : "Richie"},{$push : {"authors cited" : "Richie"}})

$addToSet添加集合并避免重复。 
db.users.update({"_id" : ObjectId(1)},{"$addToSet" : {"emails":"12@qq.com"}})

$addToSet和$each组合起来,可以添加多个不同的值。 
db.users.update({"_id" : ObjectId(1)},{"$addToSet" : {"emails" :{"$each" :["1@qq.com","2@qq.com","3@qq.com"]}}})

$pop修改器用来从数组任何一段删除元素。 
{$pop :{key : 1}}     从数组末尾删除一个元素 
{$pop :{key : -1}}    从数组头部删除一个元素

$pull用来删除基于特定条件的元素,而不仅仅是位置。 
db.users.update({},{"$pull" : {"emails" : "1@qq,.com"}})

$数组的定位修改器。除此之外,还可以通过位置定位数组(从0开始)。 
db.blog.update({"comments.author" : "John"},{"$set" : {"comment.$.auhtor" : "jim"}})

upsert是一种特殊的更新。要是没有文档符合更新条件,就会以这个条件和更新文档为基础创建一个新的文档。若找到了匹配的文档,则正常更新。 
db.users.update({"url" : "/blog"},{"$inc" : {"visitis" : 1}},true) 
最后一个参数表示upsert。

save是一个shell函数,可以在文档不存在时插入,存在实时更新。它只有一个参数:文档。

默认情况下,更新只能对符合匹配条件的第一个文档执行操作。要是有多个文档复合条件,其余的文档就没没有变化。要使所有匹配的文档都得到更新,可以设置update的第4个参数为true。 
db.users.update({birthday : "10/30/1967"},{$set : {gift : "Happy Birthday!"}},false,true) 
若想知道文档到底更新了多少文档,可以运行getLastError命令(getLastOpStatus),键值n就是想要的数字。 
db.count.update({x : 1},{$inc : {x : 1}},false,true) 
db.runCommand({getLastError : 1}){ 
        "err" : null, 
        "updateExisting" :true, 
        "n" : 5, 
        "ok" : true 
    }

getLastModify可以返回已更新的文档。 
ps = db.runCommand({"findAndModify" : "processes", "query" : {"status" : "READY"}, "sort" : {"priority" : -1}, "update" : {"$set" : {"status" : "RUNNING"}}}) 
findAndModify命令中的每个键对应的值: 
findAndModify  字符串、集合名 
query    插叙文档,用来检索文档的条件 
sort    排序结果的条件 
remove  布尔类型,表示是否删除文档 
new     布尔类型,表示返回的是更新前的文档还是更新后的文档,默认是更新前的文档 
update  修改器文档,对所有找到的文档执行更新。 
update和remove必须有一个,也只能有一个。要是匹配不到文档,则报错。

安全的版本在执行完了操作后立即运行getLastError命令,来检查是否执行成功。

数据库会为每个MongoDB数据库连接创建一个队列,存放这个连接的请求。当客户端发送一个请求,会被放到队列的末尾。只有队列中的请求都执行完毕,后续的请求才会执行。

有时查询并不需要返回所有的键/值对。可以通过find的第二个参数来指定想要的键,也可用它来剔除查询结果中的某个键/值对。 
db.users.find({},{"username" : 1, "email" : 1}) 
db.users.find({},{"sex" : 0})

查询条件 
$lt <      $lte <=      $ge >       $gte  >=      $ne  != 
db.users.find({"age" : { "$gte" : 20 , "$lte" : 30}})

MongoDB中有两种方式进行OR查询。"$in"可以用来查询一个键的多个值。"$nin"将返回与数组中所有条件都不匹配的文档。"$or"用来完成多个键值的任意给定值。 
db.raffle.find({"ticket_num" : {"$in"} : [110,119,120]}) 
db.raffle.find({"ticket_num" : {"$nin"} : [110,119,120]}) 
db.users.find({"user_id" : {"$in" : [110,"police"]}}) 
db.raffle.find({"$or" : [{"ticket_no" : 110,{"winner" : true}}]})

$not是元条件句,可以用在任何其他条件之上。 
在查询中,$lt在内层文档,而更新中$inc在外层文档的键。条件句是内层文档的键,而修改器则是外层文档的键。

db.c.find({"z" : null}) 
若要匹配所有键值为null的文档,既要检查该键的值是否为null,还要通过"$exists"条件判定键值已经存在 
db.c.find({"z" : {"$in" : [null], "$exists" : true}})

MongoDB使用Perl兼容的正则表达式(PCRE)库来匹配正则表达式,PCRE支持的正则表达式语法都能被MongoDB所接受。

$all若需要通过多个元素来匹配数组,就要用"$all"了。 
db.food.find({fruit : {$all : ["apple","banana"]}})

$size可以查询其指定长度的数组。 
db.food.insert({"_id" : 1, "fruit" : ["apple", "banana", "peach"] }) 
db.food.insert({"_id" : 2, "fruit" : ["apple", "orange", "peach"] }) 
db.food.insert({"_id" : 3, "fruit" : ["apple", "kumquat", "cherry"] })

db.food.find({"fruit"} : {"$size" : 3})

$slice返回数组的一个子集合。默认返回所有的键

返回前10条评论 
db.blog.findOne(criteria, {"comments" : {"$slice" : 10}}) 
返回最后10条评论 
db.blog.findOne(criteria, {"comments" : {"$slice" : -10}})

有两种方法查询内嵌文档:查询整个文档,或只针对其键/值对进行查询。查询文档可以包含点,来表达“深入内嵌文档内部”的意思。这就是点表示法样式插入的文档不能包含“.”的原因。将键作为url保存的时候会经常遇到这个问题。一种解决方法是在插入前或提取后执行一个全局替换,将“.”替换成一个URL中的非法字符。

使用$selemMatch这种模糊的命名条件句能用来部分指定匹配数组中的单个内嵌文档的限定条件。 
db.blog.find({"comments" : {"$selemMatch" : {"author" : "joe" , "score" : {"$gte" : 5}}}})

Monogb基本概念及基本操作的更多相关文章

  1. InfluxDB概念和基本操作 二

    InfluxDB概念和基本操作   InfluxDB基本概念 数据格式 在 InfluxDB 中,我们可以粗略的将要存入的一条数据看作一个虚拟的 key 和其对应的 value(field value ...

  2. Mysql概念及基本操作

    1.Mysql 概念 1.1 定义 数据库本质是一个C/S的套接字软件 关系型数据库:MySQL mariadb db2 非关系型:存取数据是以key:Value mongodb redis 1.2 ...

  3. python文件(概念、基本操作、常用操作、文本文件的编码方式)

    文件 目标 文件的概念 文件的基本操作 文件/文件夹的常用操作 文本文件的编码方式 01. 文件的概念 1.1 文件的概念和作用 计算机的 文件,就是存储在某种 长期储存设备 上的一段 数据 长期存储 ...

  4. InfluxDB概念和基本操作

    InfluxDB基本概念 数据格式 在 InfluxDB 中,我们可以粗略的将要存入的一条数据看作一个虚拟的 key 和其对应的 value(field value).格式如下: cpu_usage, ...

  5. 从零开始学习GDI+ (二) 基本概念与基本操作

    从零开始学习GDI+ (一)我的第一个GDI+程序 上文给新手学习GDI+讲述了vs环境等的准备工作,并且可以直接用GDI+绘图了.本文开始,讲述的可能偏理论,建议学习的过程中大胆尝试,多使用API. ...

  6. Docker 镜像、容器、仓库的概念及基本操作

    Docker 包括三个基本概念: 镜像(Image)容器(Container)仓库(Repository) 这三部分组成了Docker的整个生命周期,如下图所示,容器是由镜像实例化而来的,这和我们学习 ...

  7. 初识elasticsearch_1(基本概念和基本操作)

    初识 ElasticSearch是一个基于Lucene的搜索服务器,它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口.本博客部分基于es的官方文档.es的官方文档网址如下:h ...

  8. Oracle 用户概念与基本操作

    目录 目录 Oracle的用户 通过系统用户来登陆SQLPlus system和sys的区别 查看登陆的用户 启用和锁定一个用户 启用用户 锁定用户 创建用户 修改用户 删除用户 角色权限 常用的用户 ...

  9. python元组的概念与基本操作

    元组与列表类似,关于元组同样需要做如下三点: A.概念 1.元组通过英文状态下的圆括号构成“()”.其存放元素与列表一样,可以是不通的数值类型,也可以是不通的数据结构. 2.元组仍然是一种序列,所以几 ...

随机推荐

  1. hdu----(3118)Arbiter(构造二分图)

    Arbiter Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total S ...

  2. IntelliJ IDEA 12 与 Tomcat 集成并运行Web项目

    配置Tomcat Server 1.Ctrl+Alt+s或者File——>Setting...;选中“Application Servers”点击"+" 创建运行配置 上面的 ...

  3. 使用 HTML5 canvas 绘制精美的图形

    HTML5 是一个新兴标准,它正在以越来越快的速度替代久经考验的 HTML4.HTML5 是一个 W3C “工作草案” — 意味着它仍然处于开发阶段 — 它包含丰富的元素和属性,它们都支持现行的 HT ...

  4. 六个前端开发工程师必备的Web设计模式/模块资源(转)

    [导读] Yahoo的设计模式库Yahoo的设计模式库包含了很多可以帮助开发设计人员解决遇到的问题的资源,包括开发中常常需要处理的导航,互动效果及其布局网格等大家常用的组件和模块响应式设计模式库这个响 ...

  5. qml package 的使用

    什么时候使用这个.就是多个view使用同一个deleagte的时候. The Package class is used in conjunction with VisualDataModel to ...

  6. 在Ios里UIWebView参入js

    //修改图片大小适应webView宽高度            [webView stringByEvaluatingJavaScriptFromString:       @"var sc ...

  7. 3D开发的基本知识

    为了实现3D图形,程序员需要定义两个方面的数据: 1.3D图形的每个顶点(Vertex)的位置,每个顶点的位置都需要X.Y.Z三个左标值. 2.3D图形每个面由哪些顶点组成. Android的3D坐标 ...

  8. java模式之-模板方法模式

    模板方法模式是java设计模式常见的模式之一. <JAVA与模式>中写道: 模板方法模式是类的行为模式.准备一个抽象类,将部分逻辑以具体方法以及具体构造函数的形式实现,然后声明一些抽象方法 ...

  9. 10 notorious computer virus

    The history of computer virus is the same as computer history. With more and more powerful computers ...

  10. Redhat6.x下如何进行远程安装虚拟机

    远程主机IP:192.168.122.1 远程主机名:server1.example.com 本地主机IP:192.168.122.2 本地主机名:server2.example.com 1.登录到远 ...