文章来源:http://www.runoob.com/mongodb/mongodb-tutorial.html
NoSQL 简介
NoSQL(NoSQL = Not Only SQL ),意即"不仅仅是SQL"。
在现代的计算系统上每天网络上都会产生庞大的数据量。
这些数据有很大一部分是由关系数据库管理系统(RDMBSs)来处理。 1970年 E.F.Codd's提出的关系模型的论文 "A relational model of data for large shared data banks",这使得数据建模和应用程序编程更加简单。
通过应用实践证明,关系模型是非常适合于客户服务器编程,远远超出预期的利益,今天它是结构化数据存储在网络和商务应用的主导技术。
NoSQL 是一项全新的数据库革命性运动,早期就有人提出,发展至2009年趋势越发高涨。NoSQL的拥护者们提倡运用非关系型的数据存储,相对于铺天盖地的关系型数据库运用,这一概念无疑是一种全新的思维的注入。
关系型数据库遵循ACID规则
事务在英文中是transaction,和现实世界中的交易很类似,它有如下四个特性:
1、A (Atomicity) 原子性
原子性很容易理解,也就是说事务里的所有操作要么全部做完,要么都不做,事务成功的条件是事务里的所有操作都成功,只要有一个操作失败,整个事务就失败,需要回滚。
比如银行转账,从A账户转100元至B账户,分为两个步骤:1)从A账户取100元;2)存入100元至B账户。这两步要么一起完成,要么一起不完成,如果只完成第一步,第二步失败,钱会莫名其妙少了100元。
2、C (Consistency) 一致性
一致性也比较容易理解,也就是说数据库要一直处于一致的状态,事务的运行不会改变数据库原本的一致性约束。
例如现有完整性约束a+b=10,如果一个事务改变了a,那么必须得改变b,使得事务结束后依然满足a+b=10,否则事务失败。
3、I (Isolation) 独立性
所谓的独立性是指并发的事务之间不会互相影响,如果一个事务要访问的数据正在被另外一个事务修改,只要另外一个事务未提交,它所访问的数据就不受未提交事务的影响。
比如现有有个交易是从A账户转100元至B账户,在这个交易还未完成的情况下,如果此时B查询自己的账户,是看不到新增加的100元的。
4、D (Durability) 持久性
持久性是指一旦事务提交后,它所做的修改将会永久的保存在数据库上,即使出现宕机也不会丢失。
分布式系统
分布式系统(distributed system)由多台计算机和通信的软件组件通过计算机网络连接(本地网络或广域网)组成。
分布式系统是建立在网络之上的软件系统。正是因为软件的特性,所以分布式系统具有高度的内聚性和透明性。
因此,网络和分布式系统之间的区别更多的在于高层软件(特别是操作系统),而不是硬件。
分布式系统可以应用在在不同的平台上如:Pc、工作站、局域网和广域网上等。
分布式计算的优点
可靠性(容错) :
分布式计算系统中的一个重要的优点是可靠性。一台服务器的系统崩溃并不影响到其余的服务器。
可扩展性:
在分布式计算系统可以根据需要增加更多的机器。
资源共享:
共享数据是必不可少的应用,如银行,预订系统。
灵活性:
由于该系统是非常灵活的,它很容易安装,实施和调试新的服务。
更快的速度:
分布式计算系统可以有多台计算机的计算能力,使得它比其他系统有更快的处理速度。
开放系统:
由于它是开放的系统,本地或者远程都可以访问到该服务。
更高的性能:
相较于集中式计算机网络集群可以提供更高的性能(及更好的性价比)。
分布式计算的缺点
故障排除:
故障排除和诊断问题。
软件:
更少的软件支持是分布式计算系统的主要缺点。
网络:
网络基础设施的问题,包括:传输问题,高负载,信息丢失等。
安全性:
开发系统的特性让分布式计算系统存在着数据的安全性和共享的风险等问题。
什么是NoSQL?
NoSQL,指的是非关系型的数据库。NoSQL有时也称作Not Only SQL的缩写,是对不同于传统的关系型数据库的数据库管理系统的统称。
NoSQL用于超大规模数据的存储。(例如谷歌或Facebook每天为他们的用户收集万亿比特的数据)。这些类型的数据存储不需要固定的模式,无需多余操作就可以横向扩展。
为什么使用NoSQL ?
今天我们可以通过第三方平台(如:Google,Facebook等)可以很容易的访问和抓取数据。用户的个人信息,社交网络,地理位置,用户生成的数据和用户操作日志已经成倍的增加。我们如果要对这些用户数据进行挖掘,那SQL数据库已经不适合这些应用了, NoSQL数据库的发展也却能很好的处理这些大的数据。
实例
社会化关系网:
Separate records: UserID, first_name,last_name, age, gender,...
Task: Find all friends of friends of friends of ... friends of a given user.
Wikipedia 页面 :
Combination of structured and unstructured data
Task: Retrieve all pages regarding athletics of Summer Olympic before 1950.
RDBMS vs NoSQL
RDBMS
- 高度组织化结构化数据
- 结构化查询语言(SQL) (SQL)
- 数据和关系都存储在单独的表中。
- 数据操纵语言,数据定义语言
- 严格的一致性
- 基础事务
NoSQL
- 代表着不仅仅是SQL
- 没有声明性查询语言
- 没有预定义的模式
-键 - 值对存储,列存储,文档存储,图形数据库
- 最终一致性,而非ACID属性
- 非结构化和不可预知的数据
- CAP定理
- 高性能,高可用性和可伸缩性
NoSQL 简史
NoSQL一词最早出现于1998年,是Carlo Strozzi开发的一个轻量、开源、不提供SQL功能的关系数据库。
2009年,Last.fm的Johan Oskarsson发起了一次关于分布式开源数据库的讨论[2],来自Rackspace的Eric Evans再次提出了NoSQL的概念,这时的NoSQL主要指非关系型、分布式、不提供ACID的数据库设计模式。
2009年在亚特兰大举行的"no:sql(east)"讨论会是一个里程碑,其口号是"select fun, profit from real_world where relational=false;"。因此,对NoSQL最普遍的解释是"非关联型的",强调Key-Value Stores和文档数据库的优点,而不是单纯的反对RDBMS。
CAP定理(CAP theorem)
在计算机科学中, CAP定理(CAP theorem), 又被称作 布鲁尔定理(Brewer's theorem), 它指出对于一个分布式计算系统来说,不可能同时满足以下三点:
- 一致性(Consistency) (所有节点在同一时间具有相同的数据)
- 可用性(Availability) (保证每个请求不管成功或者失败都有响应)
- 分隔容忍(Partition tolerance) (系统中任意信息的丢失或失败不会影响系统的继续运作)
CAP理论的核心是:一个分布式系统不可能同时很好的满足一致性,可用性和分区容错性这三个需求,最多只能同时较好的满足两个。
因此,根据 CAP 原理将 NoSQL 数据库分成了满足 CA 原则、满足 CP 原则和满足 AP 原则三 大类:
- CA - 单点集群,满足一致性,可用性的系统,通常在可扩展性上不太强大。
- CP - 满足一致性,分区容忍性的系统,通常性能不是特别高。
- AP - 满足可用性,分区容忍性的系统,通常可能对一致性要求低一些。
NoSQL的优点/缺点
优点:
- - 高可扩展性
- - 分布式计算
- - 低成本
- - 架构的灵活性,半结构化数据
- - 没有复杂的关系
缺点:
- - 没有标准化
- - 有限的查询功能(到目前为止)
- - 最终一致是不直观的程序
BASE
BASE:Basically Available, Soft-state, Eventually Consistent。 由 Eric Brewer 定义。
CAP理论的核心是:一个分布式系统不可能同时很好的满足一致性,可用性和分区容错性这三个需求,最多只能同时较好的满足两个。
BASE是NoSQL数据库通常对可用性及一致性的弱要求原则:
- Basically Availble --基本可用
- Soft-state --软状态/柔性事务。 "Soft state" 可以理解为"无连接"的, 而 "Hard state" 是"面向连接"的
- Eventual Consistency --最终一致性 最终一致性, 也是是 ACID 的最终目的。
ACID vs BASE
ACID | BASE |
---|---|
原子性(Atomicity) | 基本可用(Basically Available) |
一致性(Consistency) | 软状态/柔性事务(Soft state) |
隔离性(Isolation) | 最终一致性 (Eventual consistency) |
持久性 (Durable) |
NoSQL 数据库分类
类型 | 部分代表
| 特点 |
列存储 | Hbase Cassandra Hypertable | 顾名思义,是按列存储数据的。最大的特点是方便存储结构化和半结构化数据,方便做数据压缩,对针对某一列或者某几列的查询有非常大的IO优势。 |
文档存储 | MongoDB CouchDB | 文档存储一般用类似json的格式存储,存储的内容是文档型的。这样也就有有机会对某些字段建立索引,实现关系数据库的某些功能。 |
key-value存储 | Tokyo Cabinet / Tyrant Berkeley DB MemcacheDB Redis | 可以通过key快速查询到其value。一般来说,存储不管value的格式,照单全收。(Redis包含了其他功能) |
图存储 | Neo4J FlockDB | 图形关系的最佳存储。使用传统关系数据库来解决的话性能低下,而且设计使用不方便。 |
对象存储 | db4o Versant | 通过类似面向对象语言的语法操作数据库,通过对象的方式存取数据。 |
xml数据库 | Berkeley DB XML BaseX | 高效的存储XML数据,并支持XML的内部查询语法,比如XQuery,Xpath。
|
什么是MongoDB ?
MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统。
在高负载的情况下,添加更多的节点,可以保证服务器性能。
MongoDB 旨在为WEB应用提供可扩展的高性能数据存储解决方案。
MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组成。MongoDB 文档类似于 JSON 对象。字段值可以包含其他文档,数组及文档数组。
主要特点
- MongoDB的提供了一个面向文档存储,操作起来比较简单和容易。
- 你可以在MongoDB记录中设置任何属性的索引 (如:FirstName="Sameer",Address="8 Gandhi Road")来实现更快的排序。
- 你可以通过本地或者网络创建数据镜像,这使得MongoDB有更强的扩展性。
- 如果负载的增加(需要更多的存储空间和更强的处理能力) ,它可以分布在计算机网络中的其他节点上这就是所谓的分片。
- Mongo支持丰富的查询表达式。查询指令使用JSON形式的标记,可轻易查询文档中内嵌的对象及数组。
- MongoDb 使用update()命令可以实现替换完成的文档(数据)或者一些指定的数据字段 。
- Mongodb中的Map/reduce主要是用来对数据进行批量处理和聚合操作。
- Map和Reduce。Map函数调用emit(key,value)遍历集合中所有的记录,将key与value传给Reduce函数进行处理。
- Map函数和Reduce函数是使用Javascript编写的,并可以通过db.runCommand或mapreduce命令来执行MapReduce操作。
- GridFS是MongoDB中的一个内置功能,可以用于存放大量小文件。
- MongoDB允许在服务端执行脚本,可以用Javascript编写某个函数,直接在服务端执行,也可以把函数的定义存储在服务端,下次直接调用即可。
- MongoDB支持各种编程语言:RUBY,PYTHON,JAVA,C++,PHP,C#等多种语言。
- MongoDB安装简单。
历史
- 2007年10月,MongoDB由10gen团队所发展。2009年2月首度推出。
- 2012年05月23日,MongoDB2.1 开发分支发布了! 该版本采用全新架构,包含诸多增强。
- 2012年06月06日,MongoDB 2.0.6 发布,分布式文档数据库。
- 2013年04月23日,MongoDB 2.4.3 发布,此版本包括了一些性能优化,功能增强以及bug修复。
- 2013年08月20日,MongoDB 2.4.6 发布。
- 2013年11月01日,MongoDB 2.4.8 发布。
- ……
MongoDB 下载
你可以在mongodb官网下载该安装包,地址为:https://www.mongodb.com/download-center#community。MonggoDB支持以下平台:
- OS X 32-bit
- OS X 64-bit
- Linux 32-bit
- Linux 64-bit
- Windows 32-bit
- Windows 64-bit
- Solaris i86pc
- Solaris 64
语言支持
MongoDB有官方的驱动如下:
MongoDB 工具
有几种可用于MongoDB的管理工具。
监控
MongoDB提供了网络和系统监控工具Munin,它作为一个插件应用于MongoDB中。
Gangila是MongoDB高性能的系统监视的工具,它作为一个插件应用于MongoDB中。
基于图形界面的开源工具 Cacti, 用于查看CPU负载, 网络带宽利用率,它也提供了一个应用于监控 MongoDB 的插件。
GUI
- Fang of Mongo – 网页式,由Django和jQuery所构成。
- Futon4Mongo – 一个CouchDB Futon web的mongodb山寨版。
- Mongo3 – Ruby写成。
- MongoHub – 适用于OSX的应用程序。
- Opricot – 一个基于浏览器的MongoDB控制台, 由PHP撰写而成。
- Database Master — Windows的mongodb管理工具
- RockMongo — 最好的PHP语言的MongoDB管理工具,轻量级, 支持多国语言.
MongoDB 应用案例
下面列举一些公司MongoDB的实际应用:
- Craiglist上使用MongoDB的存档数十亿条记录。
- FourSquare,基于位置的社交网站,在Amazon EC2的服务器上使用MongoDB分享数据。
- Shutterfly,以互联网为基础的社会和个人出版服务,使用MongoDB的各种持久性数据存储的要求。
- bit.ly, 一个基于Web的网址缩短服务,使用MongoDB的存储自己的数据。
- spike.com,一个MTV网络的联营公司, spike.com使用MongoDB的。
- Intuit公司,一个为小企业和个人的软件和服务提供商,为小型企业使用MongoDB的跟踪用户的数据。
- sourceforge.net,资源网站查找,创建和发布开源软件免费,使用MongoDB的后端存储。
- etsy.com ,一个购买和出售手工制作物品网站,使用MongoDB。
- 纽约时报,领先的在线新闻门户网站之一,使用MongoDB。
- CERN,著名的粒子物理研究所,欧洲核子研究中心大型强子对撞机的数据使用MongoDB。
什么是MongoDB ?
MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统。
在高负载的情况下,添加更多的节点,可以保证服务器性能。
MongoDB 旨在为WEB应用提供可扩展的高性能数据存储解决方案。
MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组成。MongoDB 文档类似于 JSON 对象。字段值可以包含其他文档,数组及文档数组。
主要特点
- MongoDB的提供了一个面向文档存储,操作起来比较简单和容易。
- 你可以在MongoDB记录中设置任何属性的索引 (如:FirstName="Sameer",Address="8 Gandhi Road")来实现更快的排序。
- 你可以通过本地或者网络创建数据镜像,这使得MongoDB有更强的扩展性。
- 如果负载的增加(需要更多的存储空间和更强的处理能力) ,它可以分布在计算机网络中的其他节点上这就是所谓的分片。
- Mongo支持丰富的查询表达式。查询指令使用JSON形式的标记,可轻易查询文档中内嵌的对象及数组。
- MongoDb 使用update()命令可以实现替换完成的文档(数据)或者一些指定的数据字段 。
- Mongodb中的Map/reduce主要是用来对数据进行批量处理和聚合操作。
- Map和Reduce。Map函数调用emit(key,value)遍历集合中所有的记录,将key与value传给Reduce函数进行处理。
- Map函数和Reduce函数是使用Javascript编写的,并可以通过db.runCommand或mapreduce命令来执行MapReduce操作。
- GridFS是MongoDB中的一个内置功能,可以用于存放大量小文件。
- MongoDB允许在服务端执行脚本,可以用Javascript编写某个函数,直接在服务端执行,也可以把函数的定义存储在服务端,下次直接调用即可。
- MongoDB支持各种编程语言:RUBY,PYTHON,JAVA,C++,PHP,C#等多种语言。
- MongoDB安装简单。
历史
- 2007年10月,MongoDB由10gen团队所发展。2009年2月首度推出。
- 2012年05月23日,MongoDB2.1 开发分支发布了! 该版本采用全新架构,包含诸多增强。
- 2012年06月06日,MongoDB 2.0.6 发布,分布式文档数据库。
- 2013年04月23日,MongoDB 2.4.3 发布,此版本包括了一些性能优化,功能增强以及bug修复。
- 2013年08月20日,MongoDB 2.4.6 发布。
- 2013年11月01日,MongoDB 2.4.8 发布。
- ……
MongoDB 下载
你可以在mongodb官网下载该安装包,地址为:https://www.mongodb.com/download-center#community。MonggoDB支持以下平台:
- OS X 32-bit
- OS X 64-bit
- Linux 32-bit
- Linux 64-bit
- Windows 32-bit
- Windows 64-bit
- Solaris i86pc
- Solaris 64
语言支持
MongoDB有官方的驱动如下:
MongoDB 工具
有几种可用于MongoDB的管理工具。
监控
MongoDB提供了网络和系统监控工具Munin,它作为一个插件应用于MongoDB中。
Gangila是MongoDB高性能的系统监视的工具,它作为一个插件应用于MongoDB中。
基于图形界面的开源工具 Cacti, 用于查看CPU负载, 网络带宽利用率,它也提供了一个应用于监控 MongoDB 的插件。
GUI
- Fang of Mongo – 网页式,由Django和jQuery所构成。
- Futon4Mongo – 一个CouchDB Futon web的mongodb山寨版。
- Mongo3 – Ruby写成。
- MongoHub – 适用于OSX的应用程序。
- Opricot – 一个基于浏览器的MongoDB控制台, 由PHP撰写而成。
- Database Master — Windows的mongodb管理工具
- RockMongo — 最好的PHP语言的MongoDB管理工具,轻量级, 支持多国语言.
MongoDB 应用案例
下面列举一些公司MongoDB的实际应用:
- Craiglist上使用MongoDB的存档数十亿条记录。
- FourSquare,基于位置的社交网站,在Amazon EC2的服务器上使用MongoDB分享数据。
- Shutterfly,以互联网为基础的社会和个人出版服务,使用MongoDB的各种持久性数据存储的要求。
- bit.ly, 一个基于Web的网址缩短服务,使用MongoDB的存储自己的数据。
- spike.com,一个MTV网络的联营公司, spike.com使用MongoDB的。
- Intuit公司,一个为小企业和个人的软件和服务提供商,为小型企业使用MongoDB的跟踪用户的数据。
- sourceforge.net,资源网站查找,创建和发布开源软件免费,使用MongoDB的后端存储。
- etsy.com ,一个购买和出售手工制作物品网站,使用MongoDB。
- 纽约时报,领先的在线新闻门户网站之一,使用MongoDB。
- CERN,著名的粒子物理研究所,欧洲核子研究中心大型强子对撞机的数据使用MongoDB。
Linux平台安装MongoDB
MongoDB 提供了 linux 各发行版本 64 位的安装包,你可以在官网下载安装包。
下载地址:https://www.mongodb.com/download-center#community
下载完安装包,并解压 tgz(以下演示的是 64 位 Linux上的安装) 。
curl -O https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.0.6.tgz # 下载 tar -zxvf mongodb-linux-x86_64-3.0.6.tgz # 解压 mv mongodb-linux-x86_64-3.0.6/ /usr/local/mongodb # 将解压包拷贝到指定目录
MongoDB 的可执行文件位于 bin 目录下,所以可以将其添加到 PATH 路径中:
export PATH=<mongodb-install-directory>/bin:$PATH
<mongodb-install-directory> 为你 MongoDB 的安装路径。如本文的 /usr/local/mongodb 。
创建数据库目录
MongoDB的数据存储在data目录的db目录下,但是这个目录在安装过程不会自动创建,所以你需要手动创建data目录,并在data目录中创建db目录。
以下实例中我们将data目录创建于根目录下(/)。
注意:/data/db 是 MongoDB 默认的启动的数据库路径(--dbpath)。
mkdir -p /data/db
命令行中运行 MongoDB 服务
你可以再命令行中执行mongo安装目录中的bin目录执行mongod命令来启动mongdb服务。
注意:如果你的数据库目录不是/data/db,可以通过 --dbpath 来指定。
$ ./mongod
2015-09-25T16:39:50.549+0800 I JOURNAL [initandlisten] journal dir=/data/db/journal 2015-09-25T16:39:50.550+0800 I JOURNAL [initandlisten] recover : no journal files present, no recovery needed 2015-09-25T16:39:50.869+0800 I JOURNAL [initandlisten] preallocateIsFaster=true 3.16 2015-09-25T16:39:51.206+0800 I JOURNAL [initandlisten] preallocateIsFaster=true 3.52 2015-09-25T16:39:52.775+0800 I JOURNAL [initandlisten] preallocateIsFaster=true 7.7
MongoDB后台管理 Shell
如果你需要进入MongoDB后台管理,你需要先打开mongodb装目录的下的bin目录,然后执行mongo命令文件。
MongoDB Shell是MongoDB自带的交互式Javascript shell,用来对MongoDB进行操作和管理的交互式环境。
当你进入mongoDB后台后,它默认会链接到 test 文档(数据库):
$ cd /usr/local/mongodb/bin $ ./mongo MongoDB shell version: 3.0.6 connecting to: test Welcome to the MongoDB shell. ……
由于它是一个JavaScript shell,您可以运行一些简单的算术运算:
> 2+2 4 > 3+6 9
现在让我们插入一些简单的数据,并对插入的数据进行检索:
> db.runoob.insert({x:10}) WriteResult({ "nInserted" : 1 }) > db.runoob.find() { "_id" : ObjectId("5604ff74a274a611b0c990aa"), "x" : 10 } >
第一个命令将数字 10 插入到 runoob 集合的 x 字段中。
MongoDb web 用户界面
MongoDB 提供了简单的 HTTP 用户界面。 如果你想启用该功能,需要在启动的时候指定参数 --rest 。
$ ./mongod --dbpath=/data/db --rest
MongoDB 的 Web 界面访问端口比服务的端口多1000。
如果你的MongoDB运行端口使用默认的27017,你可以在端口号为28017访问web用户界面,即地址为:http://localhost:28017。
Mac OSX 平台安装 MongoDB
MongoDB 提供了 OSX 平台上 64 位的安装包,你可以在官网下载安装包。
下载地址:https://www.mongodb.com/download-center#community
从 MongoDB 3.0 版本开始只支持 OS X 10.7 (Lion) 版本及更新版本的系统。
接下来我们使用 curl 命令来下载安装:
# 进入 /usr/local cd /usr/local # 下载 sudo curl -O https://fastdl.mongodb.org/osx/mongodb-osx-x86_64-3.4.2.tgz # 解压 sudo tar -zxvf mongodb-osx-x86_64-3.4.2.tgz # 重命名为 mongodb 目录 sudo mv mongodb-osx-x86_64-3.4.2 mongodb
安装完成后,我们可以把 MongoDB 的二进制命令文件目录(安装目录/bin)添加到 PATH 路径中:
export PATH=/usr/local/mongodb/bin:$PATH
使用 brew 安装
此外你还可以使用 OSX 的 brew 来安装 mongodb:
sudo brew install mongodb
如果要安装支持 TLS/SSL 命令如下:
sudo brew install mongodb --with-openssl
安装最新开发版本:
sudo brew install mongodb --devel
运行 MongoDB
1、首先我们创建一个数据库存储目录 /data/db:
sudo mkdir -p /data/db
启动 mongodb,默认数据库目录即为 /data/db:
sudo mongod # 如果没有创建全局路径 PATH,需要进入以下目录 cd /usr/local/mongodb/bin sudo ./mongod
再打开一个终端进入执行以下命令:
$ cd /usr/local/mongodb/bin $ ./mongo MongoDB shell version v3.4.2 connecting to: mongodb://127.0.0.1:27017 MongoDB server version: 3.4.2 Welcome to the MongoDB shell. …… > 1 + 1 2 >
注意:如果你的数据库目录不是/data/db,可以通过 --dbpath 来指定。
MongoDB 概念解析
不管我们学习什么数据库都应该学习其中的基础概念,在mongodb中基本的概念是文档、集合、数据库,下面我们挨个介绍。
下表将帮助您更容易理解Mongo中的一些概念:
SQL术语/概念 | MongoDB术语/概念 | 解释/说明 |
---|---|---|
database | database | 数据库 |
table | collection | 数据库表/集合 |
row | document | 数据记录行/文档 |
column | field | 数据字段/域 |
index | index | 索引 |
table joins | 表连接,MongoDB不支持 | |
primary key | primary key | 主键,MongoDB自动将_id字段设置为主键 |
通过下图实例,我们也可以更直观的的了解Mongo中的一些概念:
数据库
一个mongodb中可以建立多个数据库。
MongoDB的默认数据库为"db",该数据库存储在data目录中。
MongoDB的单个实例可以容纳多个独立的数据库,每一个都有自己的集合和权限,不同的数据库也放置在不同的文件中。
"show dbs" 命令可以显示所有数据的列表。
$ ./mongo
MongoDB shell version: 3.0.6 connecting to: test > show dbs local 0.078GB test 0.078GB >
执行 "db" 命令可以显示当前数据库对象或集合。
$ ./mongo
MongoDB shell version: 3.0.6 connecting to: test > db test >
运行"use"命令,可以连接到一个指定的数据库。
> use local switched to db local > db local >
以上实例命令中,"local" 是你要链接的数据库。
在下一个章节我们将详细讲解MongoDB中命令的使用。
数据库也通过名字来标识。数据库名可以是满足以下条件的任意UTF-8字符串。
- 不能是空字符串("")。
- 不得含有' '(空格)、.、$、/、\和\0 (空字符)。
- 应全部小写。
- 最多64字节。
有一些数据库名是保留的,可以直接访问这些有特殊作用的数据库。
- admin: 从权限的角度来看,这是"root"数据库。要是将一个用户添加到这个数据库,这个用户自动继承所有数据库的权限。一些特定的服务器端命令也只能从这个数据库运行,比如列出所有的数据库或者关闭服务器。
- local: 这个数据永远不会被复制,可以用来存储限于本地单台服务器的任意集合
- config: 当Mongo用于分片设置时,config数据库在内部使用,用于保存分片的相关信息。
文档
文档是一组键值(key-value)对(即BSON)。MongoDB 的文档不需要设置相同的字段,并且相同的字段不需要相同的数据类型,这与关系型数据库有很大的区别,也是 MongoDB 非常突出的特点。
一个简单的文档例子如下:
{"site":"www.runoob.com", "name":"菜鸟教程"}
下表列出了 RDBMS 与 MongoDB 对应的术语:
RDBMS | MongoDB |
---|---|
数据库 | 数据库 |
表格 | 集合 |
行 | 文档 |
列 | 字段 |
表联合 | 嵌入文档 |
主键 | 主键 (MongoDB 提供了 key 为 _id ) |
数据库服务和客户端 | |
Mysqld/Oracle | mongod |
mysql/sqlplus | mongo |
需要注意的是:
- 文档中的键/值对是有序的。
- 文档中的值不仅可以是在双引号里面的字符串,还可以是其他几种数据类型(甚至可以是整个嵌入的文档)。
- MongoDB区分类型和大小写。
- MongoDB的文档不能有重复的键。
- 文档的键是字符串。除了少数例外情况,键可以使用任意UTF-8字符。
文档键命名规范:
- 键不能含有\0 (空字符)。这个字符用来表示键的结尾。
- .和$有特别的意义,只有在特定环境下才能使用。
- 以下划线"_"开头的键是保留的(不是严格要求的)。
集合
集合就是 MongoDB 文档组,类似于 RDBMS (关系数据库管理系统:Relational Database Management System)中的表格。
集合存在于数据库中,集合没有固定的结构,这意味着你在对集合可以插入不同格式和类型的数据,但通常情况下我们插入集合的数据都会有一定的关联性。
比如,我们可以将以下不同数据结构的文档插入到集合中:
{"site":"www.baidu.com"} {"site":"www.google.com","name":"Google"} {"site":"www.runoob.com","name":"菜鸟教程","num":5}
当第一个文档插入时,集合就会被创建。
合法的集合名
- 集合名不能是空字符串""。
- 集合名不能含有\0字符(空字符),这个字符表示集合名的结尾。
- 集合名不能以"system."开头,这是为系统集合保留的前缀。
- 用户创建的集合名字不能含有保留字符。有些驱动程序的确支持在集合名里面包含,这是因为某些系统生成的集合中包含该字符。除非你要访问这种系统创建的集合,否则千万不要在名字里出现$。
如下实例:
db.col.findOne()
capped collections
Capped collections 就是固定大小的collection。
它有很高的性能以及队列过期的特性(过期按照插入的顺序). 有点和 "RRD" 概念类似。
Capped collections是高性能自动的维护对象的插入顺序。它非常适合类似记录日志的功能 和标准的collection不同,你必须要显式的创建一个capped collection, 指定一个collection的大小,单位是字节。collection的数据存储空间值提前分配的。
要注意的是指定的存储大小包含了数据库的头信息。
db.createCollection("mycoll", {capped:true, size:100000})
- 在capped collection中,你能添加新的对象。
- 能进行更新,然而,对象不会增加存储空间。如果增加,更新就会失败 。
- 数据库不允许进行删除。使用drop()方法删除collection所有的行。
- 注意: 删除之后,你必须显式的重新创建这个collection。
- 在32bit机器中,capped collection最大存储为1e9( 1X109)个字节。
元数据
数据库的信息是存储在集合中。它们使用了系统的命名空间:
dbname.system.*
在MongoDB数据库中名字空间 <dbname>.system.* 是包含多种系统信息的特殊集合(Collection),如下:
集合命名空间 | 描述 |
---|---|
dbname.system.namespaces | 列出所有名字空间。 |
dbname.system.indexes | 列出所有索引。 |
dbname.system.profile | 包含数据库概要(profile)信息。 |
dbname.system.users | 列出所有可访问数据库的用户。 |
dbname.local.sources | 包含复制对端(slave)的服务器信息和状态。 |
对于修改系统集合中的对象有如下限制。
在{{system.indexes}}插入数据,可以创建索引。但除此之外该表信息是不可变的(特殊的drop index命令将自动更新相关信息)。
{{system.users}}是可修改的。 {{system.profile}}是可删除的。
MongoDB 数据类型
下表为MongoDB中常用的几种数据类型。
数据类型 | 描述 |
---|---|
String | 字符串。存储数据常用的数据类型。在 MongoDB 中,UTF-8 编码的字符串才是合法的。 |
Integer | 整型数值。用于存储数值。根据你所采用的服务器,可分为 32 位或 64 位。 |
Boolean | 布尔值。用于存储布尔值(真/假)。 |
Double | 双精度浮点值。用于存储浮点值。 |
Min/Max keys | 将一个值与 BSON(二进制的 JSON)元素的最低值和最高值相对比。 |
Arrays | 用于将数组或列表或多个值存储为一个键。 |
Timestamp | 时间戳。记录文档修改或添加的具体时间。 |
Object | 用于内嵌文档。 |
Null | 用于创建空值。 |
Symbol | 符号。该数据类型基本上等同于字符串类型,但不同的是,它一般用于采用特殊符号类型的语言。 |
Date | 日期时间。用 UNIX 时间格式来存储当前日期或时间。你可以指定自己的日期时间:创建 Date 对象,传入年月日信息。 |
Object ID | 对象 ID。用于创建文档的 ID。 |
Binary Data | 二进制数据。用于存储二进制数据。 |
Code | 代码类型。用于在文档中存储 JavaScript 代码。 |
Regular expression | 正则表达式类型。用于存储正则表达式。 |
MongoDB - 连接
在本教程我们将讨论 MongoDB 的不同连接方式。
启动 MongoDB 服务
在前面的教程中,我们已经讨论了如何启动 MongoDB 服务,你只需要在 MongoDB 安装目录的 bin 目录下执行 mongod 即可。
执行启动操作后,mongodb 在输出一些必要信息后不会输出任何信息,之后就等待连接的建立,当连接被建立后,就会开始打印日志信息。
你可以使用 MongoDB shell 来连接 MongoDB 服务器。你也可以使用 PHP 来连接 MongoDB。本教程我们会使用 MongoDB shell 来连接 Mongodb 服务,之后的章节我们将会介绍如何通过php 来连接MongoDB服务。
标准 URI 连接语法:
mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]
-
mongodb:// 这是固定的格式,必须要指定。
-
username:password@ 可选项,如果设置,在连接数据库服务器之后,驱动都会尝试登陆这个数据库
-
host1 必须的指定至少一个host, host1 是这个URI唯一要填写的。它指定了要连接服务器的地址。如果要连接复制集,请指定多个主机地址。
-
portX 可选的指定端口,如果不填,默认为27017
-
/database 如果指定username:password@,连接并验证登陆指定数据库。若不指定,默认打开 test 数据库。
-
?options 是连接选项。如果不使用/database,则前面需要加上/。所有连接选项都是键值对name=value,键值对之间通过&或;(分号)隔开
标准的连接格式包含了多个选项(options),如下所示:
选项 | 描述 |
---|---|
replicaSet=name | 验证replica set的名称。 Impliesconnect=replicaSet. |
slaveOk=true|false |
|
safe=true|false |
|
w=n | 驱动添加 { w : n } 到getLastError命令. 应用于safe=true。 |
wtimeoutMS=ms | 驱动添加 { wtimeout : ms } 到 getlasterror 命令. 应用于 safe=true. |
fsync=true|false |
|
journal=true|false | 如果设置为 true, 同步到 journal (在提交到数据库前写入到实体中). 应用于 safe=true |
connectTimeoutMS=ms | 可以打开连接的时间。 |
socketTimeoutMS=ms | 发送和接受sockets的时间。 |
实例
使用默认端口来连接 MongoDB 的服务。
mongodb://localhost
通过 shell 连接 MongoDB 服务:
$ ./mongo MongoDB shell version: 3.0.6 connecting to: test ...
这时候你返回查看运行 ./mongod 命令的窗口,可以看到是从哪里连接到MongoDB的服务器,您可以看到如下信息:
……省略信息…… 2015-09-25T17:22:27.336+0800 I CONTROL [initandlisten] allocator: tcmalloc 2015-09-25T17:22:27.336+0800 I CONTROL [initandlisten] options: { storage: { dbPath: "/data/db" } } 2015-09-25T17:22:27.350+0800 I NETWORK [initandlisten] waiting for connections on port 27017 2015-09-25T17:22:36.012+0800 I NETWORK [initandlisten] connection accepted from 127.0.0.1:37310 #1 (1 connection now open) # 该行表明一个来自本机的连接 ……省略信息……
MongoDB 连接命令格式
使用用户名和密码连接到 MongoDB 服务器,你必须使用 'username:password@hostname/dbname' 格式,'username'为用户名,'password' 为密码。
使用用户名和密码连接登陆到默认数据库:
$ ./mongo MongoDB shell version: 3.0.6 connecting to: test
使用用户 admin 使用密码 123456 连接到本地的 MongoDB 服务上。输出结果如下所示:
> mongodb://admin:123456@localhost/ ...
使用用户名和密码连接登陆到指定数据库,格式如下:
mongodb://admin:123456@localhost/test
更多连接实例
连接本地数据库服务器,端口是默认的。
mongodb://localhost
使用用户名fred,密码foobar登录localhost的admin数据库。
mongodb://fred:foobar@localhost
使用用户名fred,密码foobar登录localhost的baz数据库。
mongodb://fred:foobar@localhost/baz
连接 replica pair, 服务器1为example1.com服务器2为example2。
mongodb://example1.com:27017,example2.com:27017
连接 replica set 三台服务器 (端口 27017, 27018, 和27019):
mongodb://localhost,localhost:27018,localhost:27019
连接 replica set 三台服务器, 写入操作应用在主服务器 并且分布查询到从服务器。
mongodb://host1,host2,host3/?slaveOk=true
直接连接第一个服务器,无论是replica set一部分或者主服务器或者从服务器。
mongodb://host1,host2,host3/?connect=direct;slaveOk=true
当你的连接服务器有优先级,还需要列出所有服务器,你可以使用上述连接方式。
安全模式连接到localhost:
mongodb://localhost/?safe=true
以安全模式连接到replica set,并且等待至少两个复制服务器成功写入,超时时间设置为2秒。
mongodb://host1,host2,host3/?safe=true;w=2;wtimeoutMS=2000
MongoDB 创建数据库
语法
MongoDB 创建数据库的语法格式如下:
use DATABASE_NAME
如果数据库不存在,则创建数据库,否则切换到指定数据库。
实例
以下实例我们创建了数据库 runoob:
> use runoob switched to db runoob > db runoob >
如果你想查看所有数据库,可以使用 show dbs 命令:
> show dbs local 0.078GB test 0.078GB >
可以看到,我们刚创建的数据库 runoob 并不在数据库的列表中, 要显示它,我们需要向 runoob 数据库插入一些数据。
> db.runoob.insert({"name":"菜鸟教程"}) WriteResult({ "nInserted" : 1 }) > show dbs local 0.078GB runoob 0.078GB test 0.078GB >
MongoDB 中默认的数据库为 test,如果你没有创建新的数据库,集合将存放在 test 数据库中。
MongoDB 删除数据库
语法
MongoDB 删除数据库的语法格式如下:
db.dropDatabase()
删除当前数据库,默认为 test,你可以使用 db 命令查看当前数据库名。
实例
以下实例我们删除了数据库 runoob。
首先,查看所有数据库:
> show dbs
local 0.078GB runoob 0.078GB test 0.078GB
接下来我们切换到数据库 runoob:
> use runoob
switched to db runoob
>
执行删除命令:
> db.dropDatabase() { "dropped" : "runoob", "ok" : 1 }
最后,我们再通过 show dbs 命令数据库是否删除成功:
> show dbs
local 0.078GB test 0.078GB >
删除集合
集合删除语法格式如下:
db.collection.drop()
以下实例删除了 runoob 数据库中的集合 site:
> use runoob
switched to db runoob
> show tables site > db.site.drop() true > show tables >
MongoDB 插入文档
本章节中我们将向大家介绍如何将数据插入到MongoDB的集合中。
文档的数据结构和JSON基本一样。
所有存储在集合中的数据都是BSON格式。
BSON是一种类json的一种二进制形式的存储格式,简称Binary JSON。
插入文档
MongoDB 使用 insert() 或 save() 方法向集合中插入文档,语法如下:
db.COLLECTION_NAME.insert(document)
实例
以下文档可以存储在 MongoDB 的 runoob 数据库 的 col 集合中:
>db.col.insert({title: 'MongoDB 教程', description: 'MongoDB 是一个 Nosql 数据库', by: '菜鸟教程', url: 'http://www.runoob.com', tags: ['mongodb', 'database', 'NoSQL'], likes: 100 })
以上实例中 col 是我们的集合名,如果该集合不在该数据库中, MongoDB 会自动创建该集合并插入文档。
查看已插入文档:
> db.col.find() { "_id" : ObjectId("56064886ade2f21f36b03134"), "title" : "MongoDB 教程", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 100 } >
我们也可以将数据定义为一个变量,如下所示:
> document=({title: 'MongoDB 教程', description: 'MongoDB 是一个 Nosql 数据库', by: '菜鸟教程', url: 'http://www.runoob.com', tags: ['mongodb', 'database', 'NoSQL'], likes: 100 });
执行后显示结果如下:
{
"title" : "MongoDB 教程", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 100 }
执行插入操作:
> db.col.insert(document) WriteResult({ "nInserted" : 1 }) >
插入文档你也可以使用 db.col.save(document) 命令。如果不指定 _id 字段 save() 方法类似于 insert() 方法。如果指定 _id 字段,则会更新该 _id 的数据。
笔记列表
MongoDB $type 操作符
描述
在本章节中,我们将继续讨论MongoDB中条件操作符 $type。
$type操作符是基于BSON类型来检索集合中匹配的数据类型,并返回结果。
MongoDB 中可以使用的类型如下表所示:
类型 | 数字 | 备注 |
---|---|---|
Double | 1 | |
String | 2 | |
Object | 3 | |
Array | 4 | |
Binary data | 5 | |
Undefined | 6 | 已废弃。 |
Object id | 7 | |
Boolean | 8 | |
Date | 9 | |
Null | 10 | |
Regular Expression | 11 | |
JavaScript | 13 | |
Symbol | 14 | |
JavaScript (with scope) | 15 | |
32-bit integer | 16 | |
Timestamp | 17 | |
64-bit integer | 18 | |
Min key | 255 | Query with -1. |
Max key | 127 |
我们使用的数据库名称为"runoob" 我们的集合名称为"col",以下为我们插入的数据。
简单的集合"col":
>db.col.insert({ title: 'PHP 教程', description: 'PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言。', by: '菜鸟教程', url: 'http://www.runoob.com', tags: ['php'], likes: 200 })
>db.col.insert({title: 'Java 教程', description: 'Java 是由Sun Microsystems公司于1995年5月推出的高级程序设计语言。', by: '菜鸟教程', url: 'http://www.runoob.com', tags: ['java'], likes: 150 })
>db.col.insert({title: 'MongoDB 教程', description: 'MongoDB 是一个 Nosql 数据库', by: '菜鸟教程', url: 'http://www.runoob.com', tags: ['mongodb'], likes: 100 })
使用find()命令查看数据:
> db.col.find() { "_id" : ObjectId("56066542ade2f21f36b0313a"), "title" : "PHP 教程", "description" : "PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言。", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "php" ], "likes" : 200 } { "_id" : ObjectId("56066549ade2f21f36b0313b"), "title" : "Java 教程", "description" : "Java 是由Sun Microsystems公司于1995年5月推出的高级程序设计语言。", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "java" ], "likes" : 150 } { "_id" : ObjectId("5606654fade2f21f36b0313c"), "title" : "MongoDB 教程", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "mongodb" ], "likes" : 100 }
MongoDB 操作符 - $type 实例
如果想获取 "col" 集合中 title 为 String 的数据,你可以使用以下命令:
db.col.find({"title" : {$type : 2}})
输出结果为:
{ "_id" : ObjectId("56066542ade2f21f36b0313a"), "title" : "PHP 教程", "description" : "PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言。", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "php" ], "likes" : 200 } { "_id" : ObjectId("56066549ade2f21f36b0313b"), "title" : "Java 教程", "description" : "Java 是由Sun Microsystems公司于1995年5月推出的高级程序设计语言。", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "java" ], "likes" : 150 } { "_id" : ObjectId("5606654fade2f21f36b0313c"), "title" : "MongoDB 教程", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "mongodb" ], "likes" : 100 }
MongoDB Limit与Skip方法
MongoDB Limit() 方法
如果你需要在MongoDB中读取指定数量的数据记录,可以使用MongoDB的Limit方法,limit()方法接受一个数字参数,该参数指定从MongoDB中读取的记录条数。
语法
limit()方法基本语法如下所示:
>db.COLLECTION_NAME.find().limit(NUMBER)
实例
集合 col 中的数据如下:
{ "_id" : ObjectId("56066542ade2f21f36b0313a"), "title" : "PHP 教程", "description" : "PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言。", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "php" ], "likes" : 200 } { "_id" : ObjectId("56066549ade2f21f36b0313b"), "title" : "Java 教程", "description" : "Java 是由Sun Microsystems公司于1995年5月推出的高级程序设计语言。", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "java" ], "likes" : 150 } { "_id" : ObjectId("5606654fade2f21f36b0313c"), "title" : "MongoDB 教程", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "mongodb" ], "likes" : 100 }
以上实例为显示查询文档中的两条记录:
> db.col.find({},{"title":1,_id:0}).limit(2) { "title" : "PHP 教程" } { "title" : "Java 教程" } >
注:如果你们没有指定limit()方法中的参数则显示集合中的所有数据。
MongoDB Skip() 方法
我们除了可以使用limit()方法来读取指定数量的数据外,还可以使用skip()方法来跳过指定数量的数据,skip方法同样接受一个数字参数作为跳过的记录条数。
语法
skip() 方法脚本语法格式如下:
>db.COLLECTION_NAME.find().limit(NUMBER).skip(NUMBER)
实例
以上实例只会显示第二条文档数据
>db.col.find({},{"title":1,_id:0}).limit(1).skip(1) { "title" : "Java 教程" } >
注:skip()方法默认参数为 0 。
笔记列表
-
db.col.find({},{"title":1,_id:0}).limit(2)
补充说明:
- 第一个 {} 放 where 条件,为空表示返回集合中所有文档。
- 第二个 {} 指定那些列显示和不显示 (0表示不显示 1表示显示)。
-
想要读取从 10 条记录后 100 条记录,相当于 sql 中limit (10,100)。
> db.COLLECTION_NAME.find().skip(10).limit(100)
以上实例在集合中跳过前面 10 条返回 100 条数据。
skip 和 limit 结合就能实现分页。
-
当查询时同时使用sort,skip,limit,无论位置先后,最先执行顺序 sort再skip再limit。
MongoDB 排序
MongoDB sort()方法
在MongoDB中使用使用sort()方法对数据进行排序,sort()方法可以通过参数指定排序的字段,并使用 1 和 -1 来指定排序的方式,其中 1 为升序排列,而-1是用于降序排列。
语法
sort()方法基本语法如下所示:
>db.COLLECTION_NAME.find().sort({KEY:1})
实例
col 集合中的数据如下:
{ "_id" : ObjectId("56066542ade2f21f36b0313a"), "title" : "PHP 教程", "description" : "PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言。", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "php" ], "likes" : 200 } { "_id" : ObjectId("56066549ade2f21f36b0313b"), "title" : "Java 教程", "description" : "Java 是由Sun Microsystems公司于1995年5月推出的高级程序设计语言。", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "java" ], "likes" : 150 } { "_id" : ObjectId("5606654fade2f21f36b0313c"), "title" : "MongoDB 教程", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "mongodb" ], "likes" : 100 }
以下实例演示了 col 集合中的数据按字段 likes 的降序排列:
>db.col.find({},{"title":1,_id:0}).sort({"likes":-1}) { "title" : "PHP 教程" } { "title" : "Java 教程" } { "title" : "MongoDB 教程" }
MongoDB 索引
索引通常能够极大的提高查询的效率,如果没有索引,MongoDB在读取数据时必须扫描集合中的每个文件并选取那些符合查询条件的记录。
这种扫描全集合的查询效率是非常低的,特别在处理大量的数据时,查询可以要花费几十秒甚至几分钟,这对网站的性能是非常致命的。
索引是特殊的数据结构,索引存储在一个易于遍历读取的数据集合中,索引是对数据库表中一列或多列的值进行排序的一种结构
ensureIndex() 方法
MongoDB使用 ensureIndex() 方法来创建索引。
语法
ensureIndex()方法基本语法格式如下所示:
>db.COLLECTION_NAME.ensureIndex({KEY:1})
语法中 Key 值为你要创建的索引字段,1为指定按升序创建索引,如果你想按降序来创建索引指定为-1即可。
实例
>db.col.ensureIndex({"title":1}) >
ensureIndex() 方法中你也可以设置使用多个字段创建索引(关系型数据库中称作复合索引)。
>db.col.ensureIndex({"title":1,"description":-1}) >
ensureIndex() 接收可选参数,可选参数列表如下:
Parameter Type Description background Boolean 建索引过程会阻塞其它数据库操作,background可指定以后台方式创建索引,即增加 "background" 可选参数。 "background" 默认值为false。 unique Boolean 建立的索引是否唯一。指定为true创建唯一索引。默认值为false. name string 索引的名称。如果未指定,MongoDB的通过连接索引的字段名和排序顺序生成一个索引名称。 dropDups Boolean 在建立唯一索引时是否删除重复记录,指定 true 创建唯一索引。默认值为 false. sparse Boolean 对文档中不存在的字段数据不启用索引;这个参数需要特别注意,如果设置为true的话,在索引字段中不会查询出不包含对应字段的文档.。默认值为 false. expireAfterSeconds integer 指定一个以秒为单位的数值,完成 TTL设定,设定集合的生存时间。 v index version 索引的版本号。默认的索引版本取决于mongod创建索引时运行的版本。 weights document 索引权重值,数值在 1 到 99,999 之间,表示该索引相对于其他索引字段的得分权重。 default_language string 对于文本索引,该参数决定了停用词及词干和词器的规则的列表。 默认为英语 language_override string 对于文本索引,该参数指定了包含在文档中的字段名,语言覆盖默认的language,默认值为 language. 实例
在后台创建索引:
db.values.ensureIndex({open: 1, close: 1}, {background: true})
通过在创建索引时加background:true 的选项,让创建工作在后台执行
MongoDB 聚合
MongoDB中聚合(aggregate)主要用于处理数据(诸如统计平均值,求和等),并返回计算后的数据结果。有点类似sql语句中的 count(*)。
aggregate() 方法
MongoDB中聚合的方法使用aggregate()。
语法
aggregate() 方法的基本语法格式如下所示:
>db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION)
实例
集合中的数据如下:
{ _id: ObjectId(7df78ad8902c) title: 'MongoDB Overview', description: 'MongoDB is no sql database', by_user: 'runoob.com', url: 'http://www.runoob.com', tags: ['mongodb', 'database', 'NoSQL'], likes: 100 }, { _id: ObjectId(7df78ad8902d) title: 'NoSQL Overview', description: 'No sql database is very fast', by_user: 'runoob.com', url: 'http://www.runoob.com', tags: ['mongodb', 'database', 'NoSQL'], likes: 10 }, { _id: ObjectId(7df78ad8902e) title: 'Neo4j Overview', description: 'Neo4j is no sql database', by_user: 'Neo4j', url: 'http://www.neo4j.com', tags: ['neo4j', 'database', 'NoSQL'], likes: 750 },
现在我们通过以上集合计算每个作者所写的文章数,使用aggregate()计算结果如下:
> db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : 1}}}]) { "result" : [ { "_id" : "runoob.com", "num_tutorial" : 2 }, { "_id" : "Neo4j", "num_tutorial" : 1 } ], "ok" : 1 } >
以上实例类似sql语句: select by_user, count(*) from mycol group by by_user
在上面的例子中,我们通过字段by_user字段对数据进行分组,并计算by_user字段相同值的总和。
下表展示了一些聚合的表达式:
表达式 描述 实例 $sum 计算总和。 db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : "$likes"}}}]) $avg 计算平均值 db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$avg : "$likes"}}}]) $min 获取集合中所有文档对应值得最小值。 db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$min : "$likes"}}}]) $max 获取集合中所有文档对应值得最大值。 db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$max : "$likes"}}}]) $push 在结果文档中插入值到一个数组中。 db.mycol.aggregate([{$group : {_id : "$by_user", url : {$push: "$url"}}}]) $addToSet 在结果文档中插入值到一个数组中,但不创建副本。 db.mycol.aggregate([{$group : {_id : "$by_user", url : {$addToSet : "$url"}}}]) $first 根据资源文档的排序获取第一个文档数据。 db.mycol.aggregate([{$group : {_id : "$by_user", first_url : {$first : "$url"}}}]) $last 根据资源文档的排序获取最后一个文档数据 db.mycol.aggregate([{$group : {_id : "$by_user", last_url : {$last : "$url"}}}])
管道的概念
管道在Unix和Linux中一般用于将当前命令的输出结果作为下一个命令的参数。
MongoDB的聚合管道将MongoDB文档在一个管道处理完毕后将结果传递给下一个管道处理。管道操作是可以重复的。
表达式:处理输入文档并输出。表达式是无状态的,只能用于计算当前聚合管道的文档,不能处理其它的文档。
这里我们介绍一下聚合框架中常用的几个操作:
- $project:修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档。
- $match:用于过滤数据,只输出符合条件的文档。$match使用MongoDB的标准查询操作。
- $limit:用来限制MongoDB聚合管道返回的文档数。
- $skip:在聚合管道中跳过指定数量的文档,并返回余下的文档。
- $unwind:将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。
- $group:将集合中的文档分组,可用于统计结果。
- $sort:将输入文档排序后输出。
- $geoNear:输出接近某一地理位置的有序文档。
管道操作符实例
1、$project实例
db.article.aggregate( { $project : { title : 1 , author : 1 , }} );
这样的话结果中就只还有_id,tilte和author三个字段了,默认情况下_id字段是被包含的,如果要想不包含_id话可以这样:
db.article.aggregate( { $project : { _id : 0 , title : 1 , author : 1 }});
2.$match实例
db.articles.aggregate( [ { $match : { score : { $gt : 70, $lte : 90 } } }, { $group: { _id: null, count: { $sum: 1 } } } ] );
$match用于获取分数大于70小于或等于90记录,然后将符合条件的记录送到下一阶段$group管道操作符进行处理。
3.$skip实例
db.article.aggregate( { $skip : 5 });
经过$skip管道操作符处理后,前五个文档被"过滤"掉。
笔记列表
-
db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : 1}}}])
以上实例类似sql语句:
select by_user as _id, count(*) as num_tutorial from mycol group by by_user
-
db.articles.aggregate({ $project : { title: 2, by_user: 1, } })
这样子也是可行的。也就是说非0也可以进行表示显示该字段,负数也可以表示显示该字段。
MongoDB 复制(副本集)
MongoDB复制是将数据同步在多个服务器的过程。
复制提供了数据的冗余备份,并在多个服务器上存储数据副本,提高了数据的可用性, 并可以保证数据的安全性。
复制还允许您从硬件故障和服务中断中恢复数据。
什么是复制?
- 保障数据的安全性
- 数据高可用性 (24*7)
- 灾难恢复
- 无需停机维护(如备份,重建索引,压缩)
- 分布式读取数据
MongoDB复制原理
mongodb的复制至少需要两个节点。其中一个是主节点,负责处理客户端请求,其余的都是从节点,负责复制主节点上的数据。
mongodb各个节点常见的搭配方式为:一主一从、一主多从。
主节点记录在其上的所有操作oplog,从节点定期轮询主节点获取这些操作,然后对自己的数据副本执行这些操作,从而保证从节点的数据与主节点一致。
MongoDB复制结构图如下所示:
以上结构图中,客户端从主节点读取数据,在客户端写入数据到主节点时, 主节点与从节点进行数据交互保障数据的一致性。
副本集特征:
- N 个节点的集群
- 任何节点可作为主节点
- 所有写入操作都在主节点上
- 自动故障转移
- 自动恢复
MongoDB副本集设置
在本教程中我们使用同一个MongoDB来做MongoDB主从的实验, 操作步骤如下:
1、关闭正在运行的MongoDB服务器。
现在我们通过指定 --replSet 选项来启动mongoDB。--replSet 基本语法格式如下:
mongod --port "PORT" --dbpath "YOUR_DB_DATA_PATH" --replSet "REPLICA_SET_INSTANCE_NAME"
实例
mongod --port 27017 --dbpath "D:\set up\mongodb\data" --replSet rs0
以上实例会启动一个名为rs0的MongoDB实例,其端口号为27017。
启动后打开命令提示框并连接上mongoDB服务。
在Mongo客户端使用命令rs.initiate()来启动一个新的副本集。
我们可以使用rs.conf()来查看副本集的配置
查看副本集状态使用 rs.status() 命令
副本集添加成员
添加副本集的成员,我们需要使用多条服务器来启动mongo服务。进入Mongo客户端,并使用rs.add()方法来添加副本集的成员。
语法
rs.add() 命令基本语法格式如下:
>rs.add(HOST_NAME:PORT)
实例
假设你已经启动了一个名为mongod1.net,端口号为27017的Mongo服务。 在客户端命令窗口使用rs.add() 命令将其添加到副本集中,命令如下所示:
>rs.add("mongod1.net:27017") >
MongoDB中你只能通过主节点将Mongo服务添加到副本集中, 判断当前运行的Mongo服务是否为主节点可以使用命令db.isMaster() 。
MongoDB的副本集与我们常见的主从有所不同,主从在主机宕机后所有服务将停止,而副本集在主机宕机后,副本会接管主节点成为主节点,不会出现宕机的情况。
MongoDB 分片
分片
在Mongodb里面存在另一种集群,就是分片技术,可以满足MongoDB数据量大量增长的需求。
当MongoDB存储海量的数据时,一台机器可能不足以存储数据,也可能不足以提供可接受的读写吞吐量。这时,我们就可以通过在多台机器上分割数据,使得数据库系统能存储和处理更多的数据。
为什么使用分片
- 复制所有的写入操作到主节点
- 延迟的敏感数据会在主节点查询
- 单个副本集限制在12个节点
- 当请求量巨大时会出现内存不足。
- 本地磁盘不足
- 垂直扩展价格昂贵
MongoDB分片
下图展示了在MongoDB中使用分片集群结构分布:
上图中主要有如下所述三个主要组件:
- Shard:
用于存储实际的数据块,实际生产环境中一个shard server角色可由几台机器组个一个replica set承担,防止主机单点故障
- Config Server:
mongod实例,存储了整个 ClusterMetadata,其中包括 chunk信息。
- Query Routers:
前端路由,客户端由此接入,且让整个集群看上去像单一数据库,前端应用可以透明使用。
分片实例
分片结构端口分布如下:
Shard Server 1:27020 Shard Server 2:27021 Shard Server 3:27022 Shard Server 4:27023 Config Server :27100 Route Process:40000
步骤一:启动Shard Server
[root@100 /]# mkdir -p /www/mongoDB/shard/s0 [root@100 /]# mkdir -p /www/mongoDB/shard/s1 [root@100 /]# mkdir -p /www/mongoDB/shard/s2 [root@100 /]# mkdir -p /www/mongoDB/shard/s3 [root@100 /]# mkdir -p /www/mongoDB/shard/log [root@100 /]# /usr/local/mongoDB/bin/mongod --port 27020 --dbpath=/www/mongoDB/shard/s0 --logpath=/www/mongoDB/shard/log/s0.log --logappend --fork .... [root@100 /]# /usr/local/mongoDB/bin/mongod --port 27023 --dbpath=/www/mongoDB/shard/s3 --logpath=/www/mongoDB/shard/log/s3.log --logappend --fork
步骤二: 启动Config Server
[root@100 /]# mkdir -p /www/mongoDB/shard/config [root@100 /]# /usr/local/mongoDB/bin/mongod --port 27100 --dbpath=/www/mongoDB/shard/config --logpath=/www/mongoDB/shard/log/config.log --logappend --fork
注意:这里我们完全可以像启动普通mongodb服务一样启动,不需要添加—shardsvr和configsvr参数。因为这两个参数的作用就是改变启动端口的,所以我们自行指定了端口就可以。
步骤三: 启动Route Process
/usr/local/mongoDB/bin/mongos --port 40000 --configdb localhost:27100 --fork --logpath=/www/mongoDB/shard/log/route.log --chunkSize 500
mongos启动参数中,chunkSize这一项是用来指定chunk的大小的,单位是MB,默认大小为200MB.
步骤四: 配置Sharding
接下来,我们使用MongoDB Shell登录到mongos,添加Shard节点
[root@100 shard]# /usr/local/mongoDB/bin/mongo admin --port 40000 MongoDB shell version: 2.0.7 connecting to: 127.0.0.1:40000/admin mongos> db.runCommand({ addshard:"localhost:27020" }) { "shardAdded" : "shard0000", "ok" : 1 } ...... mongos> db.runCommand({ addshard:"localhost:27029" }) { "shardAdded" : "shard0009", "ok" : 1 } mongos> db.runCommand({ enablesharding:"test" }) #设置分片存储的数据库 { "ok" : 1 } mongos> db.runCommand({ shardcollection: "test.log", key: { id:1,time:1}}) { "collectionsharded" : "test.log", "ok" : 1 }
步骤五: 程序代码内无需太大更改,直接按照连接普通的mongo数据库那样,将数据库连接接入接口40000
MongoDB 备份(mongodump)与恢复(mongorestore)
MongoDB数据备份
在Mongodb中我们使用mongodump命令来备份MongoDB数据。该命令可以导出所有数据到指定目录中。
mongodump命令可以通过参数指定导出的数据量级转存的服务器。
语法
mongodump命令脚本语法如下:
>mongodump -h dbhost -d dbname -o dbdirectory
- -h:
MongDB所在服务器地址,例如:127.0.0.1,当然也可以指定端口号:127.0.0.1:27017
- -d:
需要备份的数据库实例,例如:test
- -o:
备份的数据存放位置,例如:c:\data\dump,当然该目录需要提前建立,在备份完成后,系统自动在dump目录下建立一个test目录,这个目录里面存放该数据库实例的备份数据。
实例
在本地使用 27017 启动你的mongod服务。打开命令提示符窗口,进入MongoDB安装目录的bin目录输入命令mongodump:
>mongodump
执行以上命令后,客户端会连接到ip为 127.0.0.1 端口号为 27017 的MongoDB服务上,并备份所有数据到 bin/dump/ 目录中。命令输出结果如下:
mongodump 命令可选参数列表如下所示:
语法 描述 实例 mongodump --host HOST_NAME --port PORT_NUMBER 该命令将备份所有MongoDB数据 mongodump --host w3cschool.cc --port 27017 mongodump --dbpath DB_PATH --out BACKUP_DIRECTORY mongodump --dbpath /data/db/ --out /data/backup/ mongodump --collection COLLECTION --db DB_NAME 该命令将备份指定数据库的集合。 mongodump --collection mycol --db test
MongoDB数据恢复
mongodb使用 mongorestore 命令来恢复备份的数据。
语法
mongorestore命令脚本语法如下:
>mongorestore -h <hostname><:port> -d dbname <path>
- --host <:port>, -h <:port>:
MongoDB所在服务器地址,默认为: localhost:27017
- --db , -d :
需要恢复的数据库实例,例如:test,当然这个名称也可以和备份时候的不一样,比如test2
- --drop:
恢复的时候,先删除当前数据,然后恢复备份的数据。就是说,恢复后,备份后添加修改的数据都会被删除,慎用哦!
- <path>:
mongorestore 最后的一个参数,设置备份数据所在位置,例如:c:\data\dump\test。
你不能同时指定 <path> 和 --dir 选项,--dir也可以设置备份目录。
- --dir:
指定备份的目录
你不能同时指定 <path> 和 --dir 选项。
接下来我们执行以下命令:
>mongorestore
执行以上命令输出结果如下:
MongoDB 监控
在你已经安装部署并允许MongoDB服务后,你必须要了解MongoDB的运行情况,并查看MongoDB的性能。这样在大流量得情况下可以很好的应对并保证MongoDB正常运作。
MongoDB中提供了mongostat 和 mongotop 两个命令来监控MongoDB的运行情况。
mongostat 命令
mongostat是mongodb自带的状态检测工具,在命令行下使用。它会间隔固定时间获取mongodb的当前运行状态,并输出。如果你发现数据库突然变慢或者有其他问题的话,你第一手的操作就考虑采用mongostat来查看mongo的状态。
启动你的Mongod服务,进入到你安装的MongoDB目录下的bin目录, 然后输入mongostat命令,如下所示:
D:\set up\mongodb\bin>mongostat
以上命令输出结果如下:
mongotop 命令
mongotop也是mongodb下的一个内置工具,mongotop提供了一个方法,用来跟踪一个MongoDB的实例,查看哪些大量的时间花费在读取和写入数据。 mongotop提供每个集合的水平的统计数据。默认情况下,mongotop返回值的每一秒。
启动你的Mongod服务,进入到你安装的MongoDB目录下的bin目录, 然后输入mongotop命令,如下所示:
D:\set up\mongodb\bin>mongotop
以上命令执行输出结果如下:
带参数实例
E:\mongodb-win32-x86_64-2.2.1\bin>mongotop 10
后面的10是<sleeptime>参数 ,可以不使用,等待的时间长度,以秒为单位,mongotop等待调用之间。通过的默认mongotop返回数据的每一秒。
E:\mongodb-win32-x86_64-2.2.1\bin>mongotop --locks
报告每个数据库的锁的使用中,使用mongotop - 锁,这将产生以下输出:
输出结果字段说明:
- ns:
包含数据库命名空间,后者结合了数据库名称和集合。
-
db:
包含数据库的名称。名为 . 的数据库针对全局锁定,而非特定数据库。
-
total:
mongod花费的时间工作在这个命名空间提供总额。
-
read:
提供了大量的时间,这mongod花费在执行读操作,在此命名空间。
-
write:
提供这个命名空间进行写操作,这mongod花了大量的时间。
MongoDB Java
环境配置
在 Java 程序中如果要使用 MongoDB,你需要确保已经安装了 Java 环境及 MongoDB JDBC 驱动。
本章节实例时候 Mongo 3.x 以上版本。
你可以参考本站的Java教程来安装Java程序。现在让我们来检测你是否安装了 MongoDB JDBC 驱动。
-
首先你必须下载mongo jar包,下载地址:http://mongodb.github.io/mongo-java-driver/, 请确保下载最新版本。
- 你需要将 mongo-java-driver-3.2.2.jar (找到合适的版本)包含在你的 classpath 中。。
- 国内 mongodb-driver jar 下载地址:http://central.maven.org/maven2/org/mongodb/mongo-java-driver/
连接数据库
连接数据库,你需要指定数据库名称,如果指定的数据库不存在,mongo会自动创建数据库。
连接数据库的Java代码如下:
import com.mongodb.MongoClient; import com.mongodb.client.MongoDatabase; public class MongoDBJDBC{ public static void main( String args[] ){ try{ // 连接到 mongodb 服务 MongoClient mongoClient = new MongoClient( "localhost" , 27017 ); // 连接到数据库 MongoDatabase mongoDatabase = mongoClient.getDatabase("mycol"); System.out.println("Connect to database successfully"); }catch(Exception e){ System.err.println( e.getClass().getName() + ": " + e.getMessage() ); } } }
现在,让我们来编译运行程序并连接到数据库 mycol。
你可以根据你的实际环境改变 MongoDB JDBC 驱动的路径。
本实例将 MongoDB JDBC 启动包 mongo-java-driver-3.2.2.jar 放在本地目录下:
$ javac -cp .:mongo-java-driver-3.2.2.jar MongoDBJDBC.java $ java -cp .:mongo-java-driver-3.2.2.jar MongoDBJDBC Connect to database successfully Authentication: true
本实例中 Mongo 数据库无需用户名密码验证。如果你的 Mongo 需要验证用户名及密码,可以使用以下代码:
import java.util.ArrayList; import java.util.List; import com.mongodb.MongoClient; import com.mongodb.MongoCredential; import com.mongodb.ServerAddress; import com.mongodb.client.MongoDatabase; public class MongoDBJDBC { public static void main(String[] args){ try { //连接到MongoDB服务 如果是远程连接可以替换“localhost”为服务器所在IP地址 //ServerAddress()两个参数分别为 服务器地址 和 端口 ServerAddress serverAddress = new ServerAddress("localhost",27017); List<ServerAddress> addrs = new ArrayList<ServerAddress>(); addrs.add(serverAddress); //MongoCredential.createScramSha1Credential()三个参数分别为 用户名 数据库名称 密码 MongoCredential credential = MongoCredential.createScramSha1Credential("username", "databaseName", "password".toCharArray()); List<MongoCredential> credentials = new ArrayList<MongoCredential>(); credentials.add(credential); //通过连接认证获取MongoDB连接 MongoClient mongoClient = new MongoClient(addrs,credentials); //连接到数据库 MongoDatabase mongoDatabase = mongoClient.getDatabase("databaseName"); System.out.println("Connect to database successfully"); } catch (Exception e) { System.err.println( e.getClass().getName() + ": " + e.getMessage() ); } } }
创建集合
我们可以使用 com.mongodb.client.MongoDatabase 类中的createCollection()来创建集合
代码片段如下:
import com.mongodb.MongoClient; import com.mongodb.client.MongoDatabase; public class MongoDBJDBC{ public static void main( String args[] ){ try{ // 连接到 mongodb 服务 MongoClient mongoClient = new MongoClient( "localhost" , 27017 ); // 连接到数据库 MongoDatabase mongoDatabase = mongoClient.getDatabase("mycol"); System.out.println("Connect to database successfully"); mongoDatabase.createCollection("test"); System.out.println("集合创建成功"); }catch(Exception e){ System.err.println( e.getClass().getName() + ": " + e.getMessage() ); } } }
编译运行以上程序,输出结果如下:
Connect to database successfully 集合创建成功
获取集合
我们可以使用com.mongodb.client.MongoDatabase类的 getCollection() 方法来获取一个集合
代码片段如下:
import org.bson.Document; import com.mongodb.MongoClient; import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoDatabase; public class MongoDBJDBC{ public static void main( String args[] ){ try{ // 连接到 mongodb 服务 MongoClient mongoClient = new MongoClient( "localhost" , 27017 ); // 连接到数据库 MongoDatabase mongoDatabase = mongoClient.getDatabase("mycol"); System.out.println("Connect to database successfully"); MongoCollection<Document> collection = mongoDatabase.getCollection("test"); System.out.println("集合 test 选择成功"); }catch(Exception e){ System.err.println( e.getClass().getName() + ": " + e.getMessage() ); } } }
编译运行以上程序,输出结果如下:
Connect to database successfully 集合 test 选择成功
插入文档
我们可以使用com.mongodb.client.MongoCollection类的 insertMany() 方法来插入一个文档
代码片段如下:
import java.util.ArrayList; import java.util.List; import org.bson.Document; import com.mongodb.MongoClient; import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoDatabase; public class MongoDBJDBC{ public static void main( String args[] ){ try{ // 连接到 mongodb 服务 MongoClient mongoClient = new MongoClient( "localhost" , 27017 ); // 连接到数据库 MongoDatabase mongoDatabase = mongoClient.getDatabase("mycol"); System.out.println("Connect to database successfully"); MongoCollection<Document> collection = mongoDatabase.getCollection("test"); System.out.println("集合 test 选择成功"); //插入文档 /** * 1. 创建文档 org.bson.Document 参数为key-value的格式 * 2. 创建文档集合List<Document> * 3. 将文档集合插入数据库集合中 mongoCollection.insertMany(List<Document>) 插入单个文档可以用 mongoCollection.insertOne(Document) * */ Document document = new Document("title", "MongoDB"). append("description", "database"). append("likes", 100). append("by", "Fly"); List<Document> documents = new ArrayList<Document>(); documents.add(document); collection.insertMany(documents); System.out.println("文档插入成功"); }catch(Exception e){ System.err.println( e.getClass().getName() + ": " +
二少
272***623@qq.com
参考地址
3.2 版本后还有以下几种语法可用于插入文档:
# 插入单条数据 > var document = db.collection.insertOne({"a": 3}) > document { "acknowledged" : true, "insertedId" : ObjectId("571a218011a82a1d94c02333") } # 插入多条数据 > var res = db.collection.insertMany([{"b": 3}, {'c': 4}]) > res { "acknowledged" : true, "insertedIds" : [ ObjectId("571a22a911a82a1d94c02337"), ObjectId("571a22a911a82a1d94c02338") ] }
MongoDB 更新文档
MongoDB 使用 update() 和 save() 方法来更新集合中的文档。接下来让我们详细来看下两个函数的应用及其区别。
update() 方法
update() 方法用于更新已存在的文档。语法格式如下:
db.collection.update( <query>, <update>, { upsert: <boolean>, multi: <boolean>, writeConcern: <document> } )
参数说明:
实例
我们在集合 col 中插入如下数据:
>db.col.insert({ title: 'MongoDB 教程', description: 'MongoDB 是一个 Nosql 数据库', by: '菜鸟教程', url: 'http://www.runoob.com', tags: ['mongodb', 'database', 'NoSQL'], likes: 100 })
接着我们通过 update() 方法来更新标题(title):
>db.col.update({'title':'MongoDB 教程'},{$set:{'title':'MongoDB'}}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) # 输出信息 > db.col.find().pretty() { "_id" : ObjectId("56064f89ade2f21f36b03136"), "title" : "MongoDB", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 100 } >
可以看到标题(title)由原来的 "MongoDB 教程" 更新为了 "MongoDB"。
以上语句只会修改第一条发现的文档,如果你要修改多条相同的文档,则需要设置 multi 参数为 true。
>db.col.update({'title':'MongoDB 教程'},{$set:{'title':'MongoDB'}},{multi:true})
save() 方法
save() 方法通过传入的文档来替换已有文档。语法格式如下:
db.collection.save( <document>, { writeConcern: <document> } )
参数说明:
实例
以下实例中我们替换了 _id 为 56064f89ade2f21f36b03136 的文档数据:
>db.col.save({ "_id" : ObjectId("56064f89ade2f21f36b03136"), "title" : "MongoDB", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "Runoob", "url" : "http://www.runoob.com", "tags" : [ "mongodb", "NoSQL" ], "likes" : 110 })
替换成功后,我们可以通过 find() 命令来查看替换后的数据
>db.col.find().pretty() { "_id" : ObjectId("56064f89ade2f21f36b03136"), "title" : "MongoDB", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "Runoob", "url" : "http://www.runoob.com", "tags" : [ "mongodb", "NoSQL" ], "likes" : 110 } >
更多实例
只更新第一条记录:
全部更新:
只添加第一条:
全部添加加进去:
全部更新:
只更新第一条记录:
MongoDB 删除文档
在前面的几个章节中我们已经学习了MongoDB中如何为集合添加数据和更新数据。在本章节中我们将继续学习MongoDB集合的删除。
MongoDB remove()函数是用来移除集合中的数据。
MongoDB数据更新可以使用update()函数。在执行remove()函数前先执行find()命令来判断执行的条件是否正确,这是一个比较好的习惯。
语法
remove() 方法的基本语法格式如下所示:
db.collection.remove( <query>, <justOne> )
如果你的 MongoDB 是 2.6 版本以后的,语法格式如下:
db.collection.remove( <query>, { justOne: <boolean>, writeConcern: <document> } )
参数说明:
实例
以下文档我们执行两次插入操作:
>db.col.insert({title: 'MongoDB 教程', description: 'MongoDB 是一个 Nosql 数据库', by: '菜鸟教程', url: 'http://www.runoob.com', tags: ['mongodb', 'database', 'NoSQL'], likes: 100 })
使用 find() 函数查询数据:
> db.col.find() { "_id" : ObjectId("56066169ade2f21f36b03137"), "title" : "MongoDB 教程", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 100 } { "_id" : ObjectId("5606616dade2f21f36b03138"), "title" : "MongoDB 教程", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 100 }
接下来我们移除 title 为 'MongoDB 教程' 的文档:
>db.col.remove({'title':'MongoDB 教程'}) WriteResult({ "nRemoved" : 2 }) # 删除了两条数据 >db.col.find() …… # 没有数据
如果你只想删除第一条找到的记录可以设置 justOne 为 1,如下所示:
>db.COLLECTION_NAME.remove(DELETION_CRITERIA,1)
如果你想删除所有数据,可以使用以下方式(类似常规 SQL 的 truncate 命令):
MongoDB 查询文档
MongoDB 查询文档使用 find() 方法。
find() 方法以非结构化的方式来显示所有文档。
语法
MongoDB 查询数据的语法格式如下:
如果你需要以易读的方式来读取数据,可以使用 pretty() 方法,语法格式如下:
pretty() 方法以格式化的方式来显示所有文档。
实例
以下实例我们查询了集合 col 中的数据:
除了 find() 方法之外,还有一个 findOne() 方法,它只返回一个文档。
MongoDB 与 RDBMS Where 语句比较
如果你熟悉常规的 SQL 数据,通过下表可以更好的理解 MongoDB 的条件语句查询:
{<key>:<value>
}db.col.find({"by":"菜鸟教程"}).pretty()
where by = '菜鸟教程'
{<key>:{$lt:<value>}}
db.col.find({"likes":{$lt:50}}).pretty()
where likes < 50
{<key>:{$lte:<value>}}
db.col.find({"likes":{$lte:50}}).pretty()
where likes <= 50
{<key>:{$gt:<value>}}
db.col.find({"likes":{$gt:50}}).pretty()
where likes > 50
{<key>:{$gte:<value>}}
db.col.find({"likes":{$gte:50}}).pretty()
where likes >= 50
{<key>:{$ne:<value>}}
db.col.find({"likes":{$ne:50}}).pretty()
where likes != 50
MongoDB AND 条件
MongoDB 的 find() 方法可以传入多个键(key),每个键(key)以逗号隔开,及常规 SQL 的 AND 条件。
语法格式如下:
实例
以下实例通过 by 和 title 键来查询 菜鸟教程 中 MongoDB 教程 的数据
以上实例中类似于 WHERE 语句:WHERE by='菜鸟教程' AND title='MongoDB 教程'
MongoDB OR 条件
MongoDB OR 条件语句使用了关键字 $or,语法格式如下:
实例
以下实例中,我们演示了查询键 by 值为 菜鸟教程 或键 title 值为 MongoDB 教程 的文档。
AND 和 OR 联合使用
以下实例演示了 AND 和 OR 联合使用,类似常规 SQL 语句为: 'where likes>50 AND (by = '菜鸟教程' OR title = 'MongoDB 教程')'
MongoDB 条件操作符
描述
条件操作符用于比较两个表达式并从mongoDB集合中获取数据。
在本章节中,我们将讨论如何在MongoDB中使用条件操作符。
MongoDB中条件操作符有:
我们使用的数据库名称为"runoob" 我们的集合名称为"col",以下为我们插入的数据。
为了方便测试,我们可以先使用以下命令清空集合 "col" 的数据:
db.col.remove({})
插入以下数据
>db.col.insert({ title: 'PHP 教程', description: 'PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言。', by: '菜鸟教程', url: 'http://www.runoob.com', tags: ['php'], likes: 200 })
>db.col.insert({title: 'Java 教程', description: 'Java 是由Sun Microsystems公司于1995年5月推出的高级程序设计语言。', by: '菜鸟教程', url: 'http://www.runoob.com', tags: ['java'], likes: 150 })
>db.col.insert({title: 'MongoDB 教程', description: 'MongoDB 是一个 Nosql 数据库', by: '菜鸟教程', url: 'http://www.runoob.com', tags: ['mongodb'], likes: 100 })
使用find()命令查看数据:
> db.col.find() { "_id" : ObjectId("56066542ade2f21f36b0313a"), "title" : "PHP 教程", "description" : "PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言。", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "php" ], "likes" : 200 } { "_id" : ObjectId("56066549ade2f21f36b0313b"), "title" : "Java 教程", "description" : "Java 是由Sun Microsystems公司于1995年5月推出的高级程序设计语言。", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "java" ], "likes" : 150 } { "_id" : ObjectId("5606654fade2f21f36b0313c"), "title" : "MongoDB 教程", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "mongodb" ], "likes" : 100 }
MongoDB (>) 大于操作符 - $gt
如果你想获取 "col" 集合中 "likes" 大于 100 的数据,你可以使用以下命令:
db.col.find({"likes" : {$gt : 100}})
类似于SQL语句:
Select * from col where likes > 100;
输出结果:
> db.col.find({"likes" : {$gt : 100}}) { "_id" : ObjectId("56066542ade2f21f36b0313a"), "title" : "PHP 教程", "description" : "PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言。", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "php" ], "likes" : 200 } { "_id" : ObjectId("56066549ade2f21f36b0313b"), "title" : "Java 教程", "description" : "Java 是由Sun Microsystems公司于1995年5月推出的高级程序设计语言。", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "java" ], "likes" : 150 } >
MongoDB(>=)大于等于操作符 - $gte
如果你想获取"col"集合中 "likes" 大于等于 100 的数据,你可以使用以下命令:
db.col.find({likes : {$gte : 100}})
类似于SQL语句:
Select * from col where likes >=100;
输出结果:
> db.col.find({likes : {$gte : 100}}) { "_id" : ObjectId("56066542ade2f21f36b0313a"), "title" : "PHP 教程", "description" : "PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言。", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "php" ], "likes" : 200 } { "_id" : ObjectId("56066549ade2f21f36b0313b"), "title" : "Java 教程", "description" : "Java 是由Sun Microsystems公司于1995年5月推出的高级程序设计语言。", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "java" ], "likes" : 150 } { "_id" : ObjectId("5606654fade2f21f36b0313c"), "title" : "MongoDB 教程", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "mongodb" ], "likes" : 100 } >
MongoDB (<) 小于操作符 - $lt
如果你想获取"col"集合中 "likes" 小于 150 的数据,你可以使用以下命令:
db.col.find({likes : {$lt : 150}})
类似于SQL语句:
Select * from col where likes < 150;
输出结果:
> db.col.find({likes : {$lt : 150}}) { "_id" : ObjectId("5606654fade2f21f36b0313c"), "title" : "MongoDB 教程", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "mongodb" ], "likes" : 100 }
MongoDB (<=) 小于操作符 - $lte
如果你想获取"col"集合中 "likes" 小于等于 150 的数据,你可以使用以下命令:
db.col.find({likes : {$lte : 150}})
类似于SQL语句:
Select * from col where likes <= 150;
输出结果:
> db.col.find({likes : {$lte : 150}}) { "_id" : ObjectId("56066549ade2f21f36b0313b"), "title" : "Java 教程", "description" : "Java 是由Sun Microsystems公司于1995年5月推出的高级程序设计语言。", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "java" ], "likes" : 150 } { "_id" : ObjectId("5606654fade2f21f36b0313c"), "title" : "MongoDB 教程", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "mongodb" ], "likes" : 100 }
MongoDB 使用 (<) 和 (>) 查询 - $lt 和 $gt
如果你想获取"col"集合中 "likes" 大于100,小于 200 的数据,你可以使用以下命令:
db.col.find({likes : {$lt :200, $gt : 100}})
类似于SQL语句:
Select * from col where likes>100 AND likes<200;
输出结果:
> db.col.find({likes : {$lt :200, $gt : 100}}) { "_id" : ObjectId("56066549ade2f21f36b0313b"), "title" : "Java 教程", "description" : "Java 是由Sun Microsystems公司于1995年5月推出的高级程序设计语言。", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "java" ], "likes" : 150 } >
笔记列表
Mrt.L
903***165@qq.com
一些简写说明: