MongoDB

目录

一.初识MongoDB

1.介绍

2.作用

二.MongoDB的概念

1、数据库的概念

1.1、作用:

1.2、分类:(根据SQL语言的支持)

2、MongoDB基础概念

四、MongoDB的使用

1、连接MongoDB

1.1、DOS命令连接

1.2、点击安装目录下的mongo.exe-》E:\MongoDB\Server\4.0\bin\mongo.exe

2、基础语法

2.1、概念:

2.2、语法

3、功能与特性

3.1、索引

3.2、聚合(aggregate)

3.3、复制(副本集)

3.4、分片

3.5、备份(mongodump)与恢复(mongorestore)

3.6、监控

4、java使用MongoDB


 

参考:https://www.imooc.com/video/5934(慕课网)

参考:http://www.runoob.com/mongodb/mongodb-intro.html(菜鸟教程)

学习网站:

  • www.mongoing.com(国内官网) docs.mongoing.com(中文文档)
  • www.mongodb.org(官网)
  • www.mongodb.com
  • github.com/mongodb(源码)

 

一.初识MongoDB

1.介绍

  • 基于分布式文件存储的数据库。开源的NoSQL数据
  • 介于关系型数据库与非关系型数据库之间的产品(非关系型数据库中功能最全,最像关系型数据库的)。
  • 数据格式为类似Json的Bson格式。面向集合存储。
  • 支持的查询语言非常强大,语法类似于面向对象的查询语言,还支持对数据建立索引。
  • 特点:高性能、易部署、易使用、存储数据非常方便。(每个软件、框架都这样说......)

2.作用

  • 为WEB应用提供高性能数据存储解决方案

 

二.MongoDB的概念

1、数据库的概念

就是数据的仓库,不同的数据库存放数据的组织不同,且提供了不同种类的查询。

1.1、作用:

  • 有组织的存放数据(只需根据数据库提供的接口写入)
  • 按照不同的需求进行查询。

1.2、分类:(根据SQL语言的支持)

SQL数据库:支持SQL语言的数据库。(由于表的定义,横向扩展不够灵活。即时存取、事物操作等有时也没必要使用)

  • Oracle
  • MySql

NoSql数据库:不支持SQL语言的数据库。(没有多表连合查询)

  • Redis:键值存取,支持部分事物
  • MongoDB:本身不支持事物,没有表结构的概念

 

2、MongoDB基础概念

SQL术语/概念MongoDB术语/概念解释/说明
databasedatabase数据库
tablecollection数据库表/集合
rowdocument数据记录行/文档
columnfield数据字段/域
indexindex索引
table joins 表连接,MongoDB不支持
primary keyprimary key主键,MongoDB自动将_id字段设置为主键

 

 

 

MongoDB

Mongo

索引

集合

赋值集

分片

数据均衡

 

三、部署数据库服务

搭建简单的单击服务

搭建具有冗余容错功能的复制集

搭建大规模数据集群(拥有分片处理)

完成集群的自动部署

 

 

四、MongoDB的使用

1、连接MongoDB

语法(菜鸟教程):mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]

tips:不过好像这样输入不能连接,直接输入mongo就可以连接了

---------以下为后期补上内容--------

查看mongodb是否启动:cmd中输入 net start MongoDB  。如果没有启动服务则会重新启动(net stop MongoDB 停止启动)

mongo:是运行mongo的数据库。

mongod:启动mongo的守护进程(mongo daemon),启动mongo的服务器。(不启动服务器也可运行,但是只能用于测试)

 

 

1.1、DOS命令连接

  • 先建立环境变量“变量名:MONGODB_HOME,变量值:E:\MongoDB\Server\4.0”(如果不建立,则需通过cmd的cd命令到该目录下的bin去执行mongo.exe)
  • 在path命令中新建:“%MONGODB_HOME%\bin”
  • 然后可直接在cmd命令中输入“mongo”运行mongoDB服务(mongo好像也有的版本是mongodb)

1.2、点击安装目录下的mongo.exe-》E:\MongoDB\Server\4.0\bin\mongo.exe

 

2、基础语法

2.1、概念:

MongoDB默认数据库为test。

文档的数据结构为BSON(和JSON基本一样,是JSON的二进制形式存储格式(Binary JSON))

2.2、语法

创建数据库:use DATABASE_NAME   (如果数据库不存在,则创建。否则切换到指定数据库。)

查看所有数据库:show dbs  (刚创建的数据库如果没有插入数据,则无法通过show dbs显示)

删除数据库:db.dropDatabase()

删除集合:db.collection.drop()(collection为集合名字)

创建集合:db.createCollection(name,options)  (当插入文档时会自动创建集合)

  • name:要创建的集合名字
  • options:可选,指定有关内存大小及索引的选项
capped布尔

(可选)如果为 true,则创建固定集合。固定集合是指有着固定大小的集合,当达到最大值时,它会自动覆盖最早的文档。

当该值为 true 时,必须指定 size 参数。

autoIndexId布尔(可选)如为 true,自动在 _id 字段创建索引。默认为 false。
size数值

(可选)为固定集合指定一个最大值(以字节计)。

如果 capped 为 true,也需要指定该字段。

max数值(可选)指定固定集合中包含文档的最大数量。

插入文档同时创建集合:db.mycol2.insert({"key":"value",......})  (mycol2为集合名)

查看已有集合:show collections

插入文档:db.COLLECTION_NAME.insert(document)

定义变量:document = ({key:'value',key2:'value2'})  (定义了变量就可以通过类似参数的形式进行文档插入(如上句语法))

更新文档:db.collection.update(<query>,<update>,{upsert:<boolean>,multi:<boolean>,writeConcern:<document>})

  • 例:db.col.update({'title':'MongoDB 教程'},{$set:{'title':'MongoDB'}},{multi:true})  (更新查询到的数据的所有title)
  • 更新操作符(参考地址):https://blog.youkuaiyun.com/u014344668/article/details/52460682
  • query : update的查询条件,类似sql update查询内where后面的。
  • update : update的对象和一些更新的操作符(如$,$inc...)等,也可以理解为sql update查询内set后面的
  • upsert : 可选,这个参数的意思是,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。
  • multi : 可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。
  • writeConcern :可选,抛出异常的级别。

替换已有的文档:db.collection.save(<document>,{writeConcern:<document>})

  • document : 文档数据。
  • writeConcern :可选,抛出异常的级别。

删除文档:db.conllection.remove(<query>,{justOne:<boolean>,writeConcern:<boolean>}) 

  • 好的习惯:remove前先执行find()来判断执行条件是否正确
  • 例:db.col.remove({'title':'MongoDB 教程'},true)  (只删除第一条标题title为“MongoDB 教程”的数据)
  • query :(可选)删除的文档的条件。
  • justOne : (可选)如果设为 true 或 1,则只删除一个文档。
  • writeConcern :(可选)抛出异常的级别。

 

查询文档:db.col.find(query,projection)  (col为集合名,在加上“.pretty()”则可使查询出的内容工整)

  • query :可选,使用查询操作符指定查询条件
  • projection :可选,使用投影操作符指定返回的键。查询时返回文档中所有键值, 只需省略该参数即可(默认省略)。
    //全为1(true)或为0(false),否则错误(除了inclusion模式id可指定为0)
    db.collection.find(query, {title: 1, by: 1}) // inclusion模式 指定返回的键,不返回其他键
    db.collection.find(query, {title: 0, by: 0}) // exclusion模式 指定不返回的键,返回其他键
  • 其他:findOne()方法,只返回一个文档
  • MongoDB与RDBMS WHERE语句比较:
    操作格式范例RDBMS中的类似语句
    等于{<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条件:db.col.find({key1:value1, key2:value2}).pretty()
  • MongoDB OR条件($or):db.col.find({$or:[{key1: value1}, {key2:value2}]})  (注意与AND条件语法有点不同,因为需要让AND与OR可以联合使用)
  • AND和OR联合使用:db.col.find({"likes": {$gt:50}, $or: [{"by": "菜鸟教程"},{"title": "MongoDB 教程"}]}).pretty()
  • 还有一个条件操作符:$type

    基于BSON,检索匹配的数据类型(特殊)

    {<key>:{$type:<value>}}
    db.col.find({"title" : {$type : 2}})
    或:
    db.col.find({"title" : {$type : 'string'}})
    类型数字备注
    Double1 
    String2 
    Object3 
    Array4 
    Binary data5 
    Undefined6已废弃。
    Object id7 
    Boolean8 
    Date9 
    Null10 
    Regular Expression11 
    JavaScript13 
    Symbol14 
    JavaScript (with scope)15 
    32-bit integer16 
    Timestamp17 
    64-bit integer18 
    Min key255Query with -1.
    Max key127 

读取指定数量记录:db.COLLECTION_NAME.find().limit(NUMBER)

跳过指定数量记录:db.COLLECTION_NAME.find().limit(NUMBER).skip(NUMBER)  (先跳过,再读取指定数量)

排序:db.COLLECTION_NAME.find().sort({KEY:1})(sort({key:value})。value:1为升序、-1用于降序)

 

3、功能与特性

3.1、索引

  • 能过极大的提高查询效率。(如果没有索引,MongoDB在读取数据时必须扫描集合中的每个文件,并选取那些符合查询条件的几率)
  • 索引是特殊的数据结构,索引存储在一个易于遍历读取的数据集合中。(存储了字段的值,而值又指向记录。空间换时间)
  • 索引是对数据库表中一列或多列的值进行排序的一种结构。

创建索引:db.collection.createIndex(key,options)  

  • 例1:db.col.createIndex({"title":1}) (为字段title升序创建索引)
  • 例2:db.col.createIndex({'title':1,'description':-1})  (使用多个字段创建索引,关系型数据库也称作符合索引)
  • 例3:db.col.createIndex({open:1,close:1},{background:true})  (后台创建索引)
  • key:要创建索引的字段,1为升序建索引,-1为降序。
  • options
    ParameterTypeDescription
    backgroundBoolean建索引过程会阻塞其它数据库操作,background可指定以后台方式创建索引,即增加 "background" 可选参数。 "background" 默认值为false
    uniqueBoolean建立的索引是否唯一。指定为true创建唯一索引。默认值为false.
    namestring索引的名称。如果未指定,MongoDB的通过连接索引的字段名和排序顺序生成一个索引名称。
    dropDupsBoolean在建立唯一索引时是否删除重复记录,指定 true 创建唯一索引。默认值为 false.
    sparseBoolean对文档中不存在的字段数据不启用索引;这个参数需要特别注意,如果设置为true的话,在索引字段中不会查询出不包含对应字段的文档.。默认值为 false.
    expireAfterSecondsinteger指定一个以秒为单位的数值,完成 TTL设定,设定集合的生存时间。
    vindex version索引的版本号。默认的索引版本取决于mongod创建索引时运行的版本。
    weightsdocument索引权重值,数值在 1 到 99,999 之间,表示该索引相对于其他索引字段的得分权重。
    default_languagestring对于文本索引,该参数决定了停用词及词干和词器的规则的列表。 默认为英语
    language_overridestring对于文本索引,该参数指定了包含在文档中的字段名,语言覆盖默认的language,默认值为 language.

 

3.2、聚合(aggregate)

主要用于处理数据(诸如统计平均值,求和等),并返回计算后的数据结果。优点类似sql语句中的count(*)

语法:db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION)

例:db.mycol.aggregate([{$group : {_id:'$by_user',num_tutorial : {$sum : 1}}}])   

       类似于:select by_user,count(1) from mycol group by 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"}}}])

管道操作符:

  • $project:修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档。
  • $match:用于过滤数据,只输出符合条件的文档。$match使用MongoDB的标准查询操作。
  • $limit:用来限制MongoDB聚合管道返回的文档数。
  • $skip:在聚合管道中跳过指定数量的文档,并返回余下的文档。
  • $unwind:将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。
  • $group:将集合中的文档分组,可用于统计结果。
  • $sort:将输入文档排序后输出。
  • $geoNear:输出接近某一地理位置的有序文档。

 

3.3、复制(副本集)

  • 是将数据同步在多个服务器的过程。(分布式读取数据)
  • 提供了数据的冗余备份,并在多个服务器上存储数据副本。(提高数据可用性、保证数据安全性)
  • 允许从硬件故障、服务中断中恢复数据

3.3.1、原理

至少需要2个节点,主节点(为单个,负责处理数据端请求)、从节点(可为多,负责复制主节点上的数据)。其中主节点不是固定的一个,任何节点都可以为主节点。(因为主节点宕机后,从节点会成为主节点)

3.3.2 、特征

  • N 个节点的集群
  • 任何节点可作为主节点
  • 所有写入操作都在主节点上
  • 自动故障转移
  • 自动恢复

3.3.3、使用

  • 如果MongoDB服务在运行,先停止:net stop mongodb
  • 通过 --replSet启动MongoDB:mongod --port 12345 --dbpath "E:\MongoDB\Server\4.0\data1" --replSet rs0
    • 名为rs0,端口号为123456
  • 新开一个cmd输入:mongo  (显示则会与之前的不同,为: rs0:PRIMARY>“在这儿输入命令”)
  • rs.initiate()启动一个新的副本集、rs.conf()查看副本集配置、rs.status()查看副本集状态
  • 添加副本集成员(需要多台服务器启动mongo服务):rs.add(HOST_NAME:PORT)
    • 例:rs.add("mongod1.net:27017")
    • 只能通过主节点将Mongo(PRIMARY)服务添加到副本集中。判断是否为主节点:db.isMaster()
    • 副本集与常见的主从不同,主从再主机宕机后所有服务将停止、副本集再主机宕机后副本会接管主节点。

 

3.4、分片

  • 另一种集群,可以满足MongoDB数据量大量增长的需求。
  • 当数据量过大,一太机器不足以存储数据、不足以提供可接受的读写吞吐量。则可通过多台机器上分割数据,是的数据库系统能存储和处理更多的数据
  • 目前只做了解

3.4.1、作用:

  • 复制所有的写入操作到主节点
  • 延迟的铭感数据会在主节点查询
  • 单个副本集限制在12个节点
  • 当请求量巨大时会出现内存不足(使用分别来分割数据)
  • 本地磁盘不足
  • 垂直扩展价格昂贵

3.4.2、分片集群结构主要组件

  • shard:用于储存实际的数据块,实际生产环境中一个shard server角色可有几台机器组一个replica set承担,防止主机单点故障
  • Config Server:mongod实例,存储了整个ClusterMetadata,其中包括chunk信息
  • Query Routers:前端路由,客户端由此接入,且让整个集群看上去像单一数据库,前端应用可以透明使用。

 

3.5、备份(mongodump)与恢复(mongorestore)

备份:mongodump -h dbhost -d dbname -o dbdirectory

  • -h:MongoDB所在服务器地址。如:127.0.0.1或127.0.0.1:27017
  • -d:需要备份的数据库实例。如:test
  • -o:备份的数据存放位置。如:c:\data\dump (目录需提前建立)
  • 例:C:\Windows\system32>mongodump -h 127.0.0.1 -d test -o C:\data  (不需要(不能)再mongo下执行,打开cmd直接执行就好)
  • mongodump命令可选参数
    语法描述实例
    mongodump --host HOST_NAME --port PORT_NUMBER该命令将备份所有MongoDB数据mongodump --host runoob.com --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

恢复: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 -h 127.0.0.1 -d test --drop C:\data\test

 

3.6、监控

在你已经安装部署并允许MongoDB服务后,你必须要了解MongoDB的运行情况,并查看MongoDB的性能。这样在大流量得情况下可以很好的应对并保证MongoDB正常运作。

MongoDB中提供了mongostat 和 mongotop 两个命令来监控MongoDB的运行情况。

 

3.6.1、mongostat命令

mongodb自带的状态监测工具,在命令行下使用。它会间隔固定时间获取mongodb的当前运行状态,并输出。

如果你发现数据库突然变慢或者有其他问题的话,你第一手的操作就考虑采用mongostat来查看mongo的状态。

使用:启动你的Mongod服务,进入到你安装的MongoDB目录下的bin目录, 然后输入mongostat命令

  • 例:E:\MongoDB\Server\4.0\bin>mongostat  (如果配置了环境变量则无需进入该目录,直接输入mongostat即可)

3.6.2、mongotop命令

也是一个内置工具,提供了一个方法,用来跟踪一个MongoDB实例,查看哪些大量的时间花费在读取和写入数据。

 mongotop提供每个集合的水平的统计数据。默认情况下,mongotop返回值的每一秒。

使用:输入mongotop命令

  • 例:C:\Users\Administrator>mongotop  (配置了环境变量,可直接输入mongotop)
  • 例2:E:\mongodb-win32-x86_64-2.2.1\bin>mongotop 10
    • 后面的10是<sleeptime>参数 ,可以不使用,等待的时间长度,以秒为单位,mongotop等待调用之间。通过的默认mongotop返回数据的每一秒。
  • 例3:E:\mongodb-win32-x86_64-2.2.1\bin>mongotop --locks
    • 报告每个数据库锁的使用情况(下面为输出结果字段说明)
    • ns:包含数据库命名空间,后者结合了数据库名称和集合。
    • db:包含数据库的名称。名为 . 的数据库针对全局锁定,而非特定数据库。
    • total:mongod花费的时间工作在这个命名空间提供总额。
    • read:提供了大量的时间,这mongod花费在执行读操作,在此命名空间。
    • write:提供这个命名空间进行写操作,这mongod花了大量的时间。

 

4、java使用MongoDB

MongoDB3.0以上在连接时需要三个jar包:参考:https://blog.youkuaiyun.com/hotdust/article/details/51315197

<dependency>
	<groupId>org.mongodb</groupId>
	<artifactId>mongo-java-driver</artifactId>
	<version>3.0.4</version>
</dependency>
<dependency>
	<groupId>org.mongodb</groupId>
	<artifactId>mongodb-driver</artifactId>
	<version>3.0.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mongodb/mongodb-driver-core -->
<dependency>
	<groupId>org.mongodb</groupId>
	<artifactId>mongodb-driver-core</artifactId>
	<version>3.0.4</version>
</dependency>

MongDB在IDEA上使用实例:(使用了JUnit测试工具)


import com.mongodb.MongoClient;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.model.Filters;
import org.bson.Document;
import org.junit.Before;
import org.junit.Test;

import java.util.ArrayList;
import java.util.List;


public class MongoDBJDBC {
    //连接到数据库
    MongoDatabase mgDatabase;

    //测试时会自动在测试前运行的方法:获取MongoDB的连接
    @Before
    public void getmgDatabase(){
        try{
            //连接到mongodb服务
            MongoClient mgClient = new MongoClient("localhost",27017);
            //连接到数据库
            mgDatabase = mgClient.getDatabase("test");
            System.out.println("连接成功");

        }catch(Exception e){
            System.err.println( e.getClass().getName() + ": " + e.getMessage() );
        }
    }

    //当连接数据库需要用户名、密码时使用
//    @Before
//    public void getmgDatabase(){
//        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);
//
//            //连接到数据库
//            mgDatabase = mongoClient.getDatabase("databaseName");
//            System.out.println("数据库连接成功");
//        } catch (Exception e) {
//            System.err.println( e.getClass().getName() + ": " + e.getMessage() );
//        }
//    }

    //1.创建集合
    @Test
    public void createConllection(){
        mgDatabase.createCollection("test2");
        System.out.println("集合创建成功");
    }

    //2.获取集合
    @Test
    public void getCollection(){
        MongoCollection<Document> collection  =  mgDatabase.getCollection("test");
        System.out.println("集合test选择成功");
    }

    //3.插入文档
    @Test
    public void insertDocument(){
        MongoCollection<Document> collection  =  mgDatabase.getCollection("test");
        System.out.println("集合test选择成功");
        //插入文档
        /**
         * 1. 创建文档 org.bson.Document 参数为key-value的格式
         * 2. 创建文档集合List<Document>
         * 3. 将文档集合插入数据库集合中 collection.insertMany(List<Document>) 插入单个文档可以用 collection.insertOne(Document)
         * */
        Document document = new Document("title","MongoDB").
                append("description", "database").
                append("likes", 101).
                append("by", "又是一条记录");
        List<Document> documents = new ArrayList<Document>();
        documents.add(document);

        collection.insertMany(documents);
        System.out.println("文档插入成功");
    }

    //4.检查所有文档
    @Test
    public void findDocument(){
        MongoCollection<Document> collection  =  mgDatabase.getCollection("test");
        System.out.println("集合test选择成功");

        //检索所有文档
        /**
         * 1. 获取迭代器FindIterable<Document>
         * 2. 获取游标MongoCursor<Document>
         * 3. 通过游标遍历检索出的文档集合
         * */
        FindIterable<Document> findIterable = collection.find();
        MongoCursor<Document> mgCursor = findIterable.iterator();
        while(mgCursor.hasNext()){
            System.out.println(mgCursor.next());
        }

        System.out.println("检查完成");
    }

    //5.更新文档
    @Test
    public void updateDocument(){
        MongoCollection<Document> collection  =  mgDatabase.getCollection("test");
        System.out.println("集合test选择成功");

        //更新文档  将文档中likes=100的文档修改为likes=200
        collection.updateMany(Filters.eq("likes",101),new Document("$set",new Document("likes",210)));

        System.out.println("集合更新成功");
    }

    //6.1、删除第一个文档
    @Test
    public void deleteOneDocument(){
        MongoCollection<Document> collection  =  mgDatabase.getCollection("test");
        System.out.println("集合test选择成功");

        //删除符合条件的第一个文档
        collection.deleteOne(Filters.eq("likes",200));

        System.out.println("删除符合条件的第一个文档成功");
    }

    //6.1、删除符合条件的所有文档
    @Test
    public void deleteManyDocument(){
        MongoCollection<Document> collection  =  mgDatabase.getCollection("test");
        System.out.println("集合test选择成功");

        //删除符合条件的所有文档(就是变了一个deleteMany方法)
        collection.deleteMany(Filters.eq("likes",210));

        System.out.println("删除符合条件的所有文档成功");
    }

}

 

五、MongoDB高级教程

1、MongoDB关系

表示多个文档在逻辑上的相互联系。

文档间可以通过嵌入引用来建立联系。

关系:

  • 1:1(1对1)
  • 1:N(一对多)
  • N:1(多对1)
  • N:N(多对多)

例:一个用户可以有多个地址(这个只是一个说明,不做实际应用)

//user文档简单结构
{
   "_id":ObjectId("52ffc33cd85242f436000001"),
   "name": "Tom Hanks",
   "contact": "987654321",
   "dob": "01-01-1991"
}


//address文档简单结构
{
   "_id":ObjectId("52ffc4a5d85242602e000000"),
   "building": "22 A, Indiana Apt",
   "pincode": 123456,
   "city": "Los Angeles",
   "state": "California"
} 

1.1、嵌入式关系

  • 使用嵌入式关系,我们可以把用户地址嵌入到用户的文档中。
  • 不足:如果用户和用户地址在不断增加,数据量不断变大,会影响读写性能
//不用想复杂了,就是将地址以数组的形式保存在address中
   "_id":ObjectId("52ffc33cd85242f436000001"),
   "contact": "987654321",
   "dob": "01-01-1991",
   "name": "Tom Benzamin",
   "address": [
      {
         "building": "22 A, Indiana Apt",
         "pincode": 123456,
         "city": "Los Angeles",
         "state": "California"
      },
      {
         "building": "170 A, Acropolis Apt",
         "pincode": 456789,
         "city": "Chicago",
         "state": "Illinois"
      }]
} 



//可以使用这种方式来查询地址
>db.users.findOne({"name":"Tom Benzamin"},{"address"}:1)
//只显示满足条件的地址
db.test.find({"address":{$elemMatch:{"pincode":123456}}},{address:{$elemMatch:{"pincode":123456}}}).pretty()

 

1.2、引用式关系

引用式关系是设计数据库时经常用到的方法,这种方法把用户数据文档和用户地址数据文档分开,通过引用文档的id字段来建立关系。

//1、插入用户记录
> db.user.insert({
...    "_id":ObjectId("52ffc33cd85242f436000001"),
...    "contact": "987654321",
...    "dob": "01-01-1991",
...    "name": "Tom Benzamin",
...    "address_ids": [
...       ObjectId("52ffc4a5d85242602e000000"),
...       ObjectId("52ffc4a5d85242602e000001")
...    ]
... })

//2、插入城市记录
> db.address.insert({address:"长沙"})
WriteResult({ "nInserted" : 1 })
> db.address.insert({address:"北京"})
WriteResult({ "nInserted" : 1 })
> db.address.insert({address:"上海"})
WriteResult({ "nInserted" : 1 })
> db.address.insert({address:"广州"})
WriteResult({ "nInserted" : 1 })
> db.address.insert({address:"郴州"})
WriteResult({ "nInserted" : 1 })

//3、中间省略查询城市记录步骤(获取_id)

//4、修改用户的地址(address_ids)为查询出的地址"_id"
> db.user.update({contact:"987654321"},{$set:{address_ids:[ObjectId("5b7693f2ddc293f504101a07"), ObjectId("5b7693f8ddc293f504101a08")]}})

//5、获取用户的地址id
> var result = db.user.findOne({"name":"Tom Benzamin"},{"address_ids":1})

//6、获取相关联的地址(可直接输入变量名输出)
>var address = db.address.find({_id:{"$in":result["address_ids"]}})

 

2.数据库引用

  • 在4.1中的引用式关系中,引用又分为两种:手动引用(Manual References)、DBRefs
  • 理解:我们在不同的集合中 (address_home, address_office, address_mailing, 等)存储不同的地址(住址,办公室地址,邮件地址等)。这样,我们在调用不同地址时,也需要指定集合,一个文档从多个集合引用文档,我们应该使用 DBRefs。

DBRef的形式:{ $ref : , $id : , $db : }

  • $ref:集合名称
  • $id:引用的id
  • $db:数据库名称,可选参数
  • 实例:
    //address DBRef 字段指定了引用的地址文档是在 runoob 数据库下的 address_home 集合,id 为 534009e4d852427820000002。
    {
       "_id":ObjectId("53402597d852426020000002"),
       "address": {
       "$ref": "address_home",
       "$id": ObjectId("534009e4d852427820000002"),
       "$db": "runoob"},
       "contact": "987654321",
       "dob": "01-01-1991",
       "name": "Tom Benzamin"
    }
    
    
    //我们通过指定 $ref 参数(address_home 集合)来查找集合中指定id的用户地址信息:
    >var user = db.users.findOne({"name":"Tom Benzamin"})
    >var dbRef = user.address
    >db[dbRef.$ref].findOne({"_id":(dbRef.$id)})
    
    //结果
    {
       "_id" : ObjectId("534009e4d852427820000002"),
       "building" : "22 A, Indiana Apt",
       "pincode" : 123456,
       "city" : "Los Angeles",
       "state" : "California"
    }

     

3、覆盖索引查询

达成覆盖索引查询的条件:

  • 所有的查询字段是索引的一部分(“一部分” 的理解就是:有可能这个字段是数组或文档,但是又与“不能达成”有冲突了)
  • 所有的查询返回字段在同一个索引中

原理:

  • 由于所有出现在查询中的字段是索引的一部分, MongoDB 无需在整个数据文档中检索匹配 查询条件和返回 使用相同索引的查询结果。
  • 因为索引存在于RAM中,从索引中获取数据比通过扫描文档读取数据要快得多。

例:

//user集合
{
   "_id": ObjectId("53402597d852426020000002"),
   "contact": "987654321",
   "dob": "01-01-1991",
   "gender": "M",
   "name": "Tom Benzamin",
   "user_name": "tombenzamin"
}

//创建联合索引,字段为 gender 和 user_name :
>db.users.ensureIndex({gender:1,user_name:1})


//执行查询,该索引会覆盖这次查询(MongoDB的不会去数据库文件中查找。相反,它会从索引中提取数据,这是非常快速的数据查询。)
//由于我们的索引中不包括 _id 字段,_id在查询中会默认返回,我们可以在MongoDB的查询结果集中排除它。
>db.users.find({gender:"M"},{user_name:1,_id:0})    

//执行查询(这种不会覆盖,因为他没有排除id)
>db.users.find({gender:"M"},{user_name:1})

以下的查询,不能使用覆盖索引查询:

  • 所有索引字段是一个数组
  • 所有索引字段是一个子文档

 

 

2.2

1、文档的读写更新删除

2、各种不同类型的索引的创建与使用

3、复杂的聚合查询

4、对数据集合进行分片,在不同分片中维持数据均衡

5、数据备份与恢复

6、数据迁移

 

五、运维

1、部署MongoDb集群

2、处理多种常见故障(保证集群的正常运行)

单节点失效如何恢复工作

数据库意外被杀死,如何进行数据恢复

数据库发生拒绝服务时如何排查原因

数据库磁盘快满时如何处理

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值