MongoDB学习笔记

 

  

MongoDB学习笔记

“nosql现在在网站开发中应用的越来越广泛,其中的MongoDB被大量使用。MongoDB 作为一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的,也是我们所必须掌握的一个产品。”

 

首先我需要感谢一下这两位老哥:konghouy和 DeeJay_Y,我是以他们的文章为基础进行学习的。献上他们的文章链接:

    https://blog.csdn.net/konghouy/article/details/90146763

    https://www.jianshu.com/p/72fc4409936c

另外还有菜鸟教程的链接:https://www.runoob.com/mongodb/mongodb-tutorial.html

   MongoDB官网链接:https://www.mongodb.org.cn/   

 

正文

 

01

什么是NoSql

  NoSQL最常见的解释是“non-relational”, “Not Only SQL”也被很多人接受。NoSQL仅仅是一个概念,泛指非关系型的数据库,区别于关系数据库,它们不保证关系数据的ACID特性。NoSQL有如下优点:易扩展,NoSQL数据库种类繁多,但是一个共同的特点都是去掉关系数据库的关系型特性。数据之间无关系,这样就非常容易扩展。无形之间也在架构的层面上带来了可扩展的能力。大数据量,高性能,NoSQL数据库都具有非常高的读写性能,尤其在大数据量下,同样表现优秀。这得益于它的无关系性,数据库的结构简单。

https://baike.baidu.com/item/NoSQL/8828247?fr=aladdin

NoSql可以分成4类:

  • 键值(Key-Value)存储数据库

    这一类数据库主要会使用到一个哈希表,这个表中有一个特定的键和一个指针指向特定的数据。Key/value模型对于IT系统来说的优势在于简单、易部署。但是如果DBA只对部分值进行查询或更新的时候,Key/value就显得效率低下了。举例如:Tokyo Cabinet/Tyrant, Redis, Voldemort, Oracle BDB。用大白话来讲就是一个map

  • 列存储数据库

    这部分数据库通常是用来应对分布式存储的海量数据。键仍然存在,但是它们的特点是指向了多个列。这些列是由列家族来安排的。如:Cassandra, HBase, Riak。这个我没用过,不甚了解。

  • 文档型数据库

    文档型数据库的灵感是来自于Lotus Notes办公软件的,而且它同第一种键值存储相类似。该类型的数据模型是版本化的文档,半结构化的文档以特定的格式存储,比如JSON。文档型数据库可 以看作是键值数据库的升级版,允许之间嵌套键值。而且文档型数据库比键值数据库的查询效率更高。如:CouchDB, MongoDb. 国内也有文档型数据库SequoiaDB,已经开源。存储的内容是类似JSON格式的数据。

  • 图形(Graph)数据库

    图形结构的数据库同其他行列以及刚性结构的SQL数据库不同,它是使用灵活的图形模型,并且能够扩展到多个服务器上。NoSQL数据库没有标准的查询语言(SQL),因此进行数据库查询需要制定数据模型。许多NoSQL数据库都有REST式的数据接口或者查询API。如:Neo4J, InfoGrid, Infinite Graph。

 MongoDB学习笔记_第1张图片

 

 

 

02

什么是MongoDB

 

  MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统。在高负载的情况下,添加更多的节点,可以保证服务器性能。MongoDB 旨在为WEB应用提供可扩展的高性能数据存储解决方案。MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组成。MongoDB 文档类似于 JSON 对象。字段值可以包含其他文档,数组及文档数组。MongoDB 是一个基于分布式文件存储的数据库。由 C++ 语言编写。旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。

 MongoDB学习笔记_第2张图片

 

 

 

 

03

MongoDB安装

 

具体安装过程自己百度吧。这里我给出菜鸟教程的安装教程地址:https://www.runoob.com/mongodb/mongodb-window-install.html

 

 

我自己在安装没有遇到坑,但是这里收集了别人遇到的问题。

  1. install mongoDB compass

    安装过程中勾选了安装install mongoDB compass,导致安装程序一直卡在那块。最后要重新安装了一次才解决了问题。mongoDB compass是个图形化界面,后期可以自己安装。MongoDB图形化界面挺多的,自己后期挑个喜欢的就好。我个人喜欢robo 3T

  2. 安装在其他盘时,安装过程提示错误。

    MongoDB默认装在C盘,安装程序可以直接获取管理员权限。但是当我们装在其他盘时,就没这么好运了。这就需要我们使用管理员身份运行安装程序。

  3. 安装MongoDB服务出现问题

    当程序安装完成之后,就需要安装windows服务了,MongoDB中已经为我们写好了配置文件,通过这个配置文件,即可安装windows服务。具体的命令是:mongod --config "E:\MongoDB\bin\mongod.cfg" --install本想着,安装服务然后启动服务就可以可以使用了,但是这样却出现了问题:Unrecognized option:mp 这就令人非常抓狂了,配置文件是官方提供的,它怎么能说mp是无效的属性呢?直接干掉这个mp这一行就行了。

  4. MongoDB需要配置数据文件存放位置和日志存放位置,不然无法运行。

  5. 配置文件中不能使用Tab键进行缩进。属性名与属性值之间,必须用 :空格 进行连接,如果不添加空格,属性将无法识别

 

MongoDB服务相关的命令:

删除windows服务:sc delete MongoDB

启动服务 :net start MongoDB

停止服务:net stop MongoDB

更新服务配置:mongod -f E:\MongoDB\bin\mongod.cfg

 

 

04

数据库连接及权限管理

 

  使用MongoDB中有一个很大的困惑,既然不需要密码就可以登录?那它的安全性如何保证呢?权限划分又是如何进行呢?对比MySQL在安装成功之后就会有个初始密码,MongoDB是不是不安全呢?

  MongoDB默认是不需要输入用户名和密码,客户就可以登录的,获得管理员权限。不过会出现好多好多Warning。

MongoDB学习笔记_第3张图片

 

 

 

 出于安全性的考虑,我们还是要为其设置用户名和密码。

 

步骤1:先以不需要密码的形式登录,进入admin库。

1 use admin;

 

步骤二:往admin表中插入一个超级管理员用户。

db.createUser({    
  user:"root",
  pwd:"root",
  roles:[{role:"root",db:"admin"}]
})

 

步骤三:查看用户是否插入成功。

1 show users

 

步骤四:在配置文件中添加auth=true

 

 

注意,如果是使用MongoDB自动生成的配置文件,写法则与自建的配置文件不同。不能用tab,冒号后面必须有个空格。具体参数参考:

http://docs.mongodb.org/manual/reference/configuration-options/

 MongoDB学习笔记_第4张图片

 

MongoDB学习笔记_第5张图片

 

 

 

 

 // 增加这两行
 security:  
   authorization: enabled

 

步骤五:重启MongoDB。

net stop mongodb (关闭服务)
net start mongodb (开启服务)

 

步骤六:使用账户密码连接MongoDB,authenticationDatabase 参数为要验证的数据库。

mongo.exe --host "localhost" --port "27017" -u "root" -p "root" --authenticationDatabase "admin"

 

 

 

相关数据库角色:

  • 数据库用户角色(Database User Roles):

        read:授予User只读数据的权限。

        readWrite:授予User读写数据的权限。

 

  • 数据库管理角色(Database Administration Roles):

        dbAdmin:在当前dB中执行管理操作。

        dbOwner:在当前DB中执行任意操作。

        userAdmin:在当前DB中管理User。

 

  • 备份和还原角色(Backup and Restoration Roles):

        backup

        restore

 

  • 跨库角色(All-Database Roles):

        readAnyDatabase:只能在admin库中添加,授予在所有数据库上读取数据的权限。

        readWriteAnyDatabase:只能在admin库中添加,授予在所有数据库上读写数据的权限。

        userAdminAnyDatabase:只能在admin库中添加,授予在所有数据库上管理User的权限。

        dbAdminAnyDatabase:只能在admin库中添加,授予管理所有数据库的权限。

 

  • 集群管理角色(Cluster Administration Roles):

        clusterAdmin:只能在admin库中添加,授予管理集群的最高权限。

        clusterManager:只能在admin库中添加,授予管理和监控集群的权限。

        clusterMonitor:只能在admin库中添加,授予监控集群的权限,对监控工具具有readonly的权限。

        hostManager:只能在admin库中添加,管理Server。

 

  • 超级管理员:

        root : 只能在admin库中添加,超级账号,超级权限

 

相关角色的操作:

    1、 在shell中切换用户角色:

db.auth(“user”,“pwd”);

 

    2、修改密码:

方法1:db.changeUserPassword(“usertest”,“changepass”);
方法2:db.updateUser(“usertest”,{pwd:“changepass1”});

 

    3、修改权限:

// updateUser它是完全替换之前的值
db.updateUser(“usertest”,{roles:[ {role:“read”,db:“testDB”} ]})

 

    4、增加权限:

# 修改权限
db.grantRolesToUser(  “usertest”,   [    {role:“readWrite”, db:“testDB”},    {role:“read”, db:“testDB”}  ])

 

    5、删除权限:

db.revokeRolesFromUser(“usertest”,[{role:“read”, db:“testDB”}]);

 

 

 

 

 

05

MongoDB的数据类型

 MongoDB学习笔记_第6张图片

 

 

 MongoDB学习笔记_第7张图片

 

 

 

 

各类型对应的数字表示:

MongoDB学习笔记_第8张图片

 

 

 

上面的大部分类型都是显而易见的,但是有必要详细解释一下对象 id类型。我们上面说了,对象 id类型是一个 12字节的唯一 id。每个字节 2位 16进制数(1字节8位,4位一个十六进制数),因此整个 id类型是一个 24位的字符串。其结构如下表所示:

 

 

 

 

 前 4 个字节表示创建 unix 时间戳,格林尼治时间 UTC 时间,比北京时间晚了 8 个小时。接下来三个字节表示机器号,一般是机器名的hash值。这可以保证不同机器产生的id不会冲突。接下来两个字节表示进程id号,保证统一机器不同进程产生的id不冲突。最后三个是计数器的计数值,对于任意一秒钟,可以产生2^24个数。

06

MongoDB的一些概念

MongoDB学习笔记_第9张图片

 

 

MongoDB的三个特殊库:

MongoDB学习笔记_第10张图片

 

 

 

admin:从权限的角度来看,这是"root"数据库。要是将一个用户添加到这个数据库,这个用户自动继承所有数据库的权限。一些特定的服务器端命令也只能从这个数据库运行,比如列出所有的数据库或者关闭服务器。

local: 这个数据永远不会被复制,可以用来存储限于本地单台服务器的任意集合。

config: 当Mongo用于分片设置时,config数据库在内部使用,用于保存分片的相关信息。

 

 

MongoDB中严格区分大小写,特别是命令。

 

 

MongoDB的连接:

MongoDB学习笔记_第11张图片

 

MongoDB中的两种连接方式:

  direct:只连接一台服务器,不管他是不是主服务器。

  replicaSet:连接多台服务器。

 

MongoDB学习笔记_第12张图片

 

 

07

MongoDB的基本使用

 

1、创建数据库:

// 如果数据库不存在,那么在插入第一条数据后,便会自动创建数据库
use dbName;

 

【注意】数据库创建,必须要插入一条数据后, show dbs 命令才会显示,数据库已经添加

 

2、查看数据库

// 显示权限范围内的数据库db;        
// 显示当前数据库
show dbs; 

 

 

3、删除数据库

 // 删除当前数据库
db.dropDatabase();   

 

 

4、创建集合

db.createCollection(name, options);
db.createCollection("mycol",{
  capped : true,
  autoIndexId : true,
  size :6142800,
  max : 10000
} )

 

参数说明:

  • name: 要创建的集合名称

  • options: 可选参数, 指定有关内存大小及索引的选项

options 可以是如下参数:

MongoDB学习笔记_第13张图片

 

 

 

注意:

  1. 如果要创建固定大小的集合,必须显示创建,自动创建的集合都是不定长的集合。

  2. 插入文档时,会先判断size参数,空间足够才判断max,只有两者都满足,才能插入成功。

 

5、获取集合:

db.getCollection("集合名");
db.集合名

 

6、查看所有集合:

show tables;show collections;  // 这个命令更适合MongoDB

 

7、删除集合:

db.getCollection("集合名").drop()// 这里要注意和删除数据库进行区分
db.dropDatabase();

 

8、插入文档:

// 参数为json,可以是数组,也可以是对象,只要满足json格式就行
db.getCollection("集合名").insert({"name":"张三","age":15});
db.getCollection("集合名").save({"name":"张三","age":15});
db.getCollection("集合名").insertOne({"name":"张三","age":15});
db.getCollection("集合名").insertMany([ {"name":"张三","age":15}, {"name":"栗子","age":25}]);

 

说明:

  • insertOne()只能插入一个文档,如果传入一个数组,则报错。

  • insertMany()只能插入数组,如果传入不是数组,则报错。

  • insert()如果传入数组,则插入多个文档;如果传入单个对象,则插入一个文档;如果_id不填写,自动生成objectId;如果_id已存在,则报错。

  • save()和insert()基本一样,但是当_id存在时,save()会直接更新该_id对应的整个文档

 

9、查询文档

// query为查询条件,projection为映射字段
db.getCollection("集合名").find(query, projection);
// 相当于SQL: select <projection> from "集合名" where <query>

 MongoDB学习笔记_第14张图片

 MongoDB学习笔记_第15张图片

说明:

  • $lt ==> less than

  • $gt => greater than

  • $lte ==> less than or equal

  • $ne ==> not equal

  • 多个条件逗号隔开,默认就是and,如果是or,则需要$or:[{条件},{条件}]。$or中每个元素都必须是对象。

  • $type的值可以是类型对应的数字,也可以是类型字符串(首字母需要小写)

// 查询姓名中有个张字的15-20岁的学生,他可能是四班的,// 也有可能是李四老师教的学生
db.getCollection("student").find({  
  name:"
^\w*张\w*$",
  age:{$lt:20,$gt:15},
  $or:[
    {class:"四班"},
    {teacher:"李四"}
  ]
});

 

projection :可选,使用投影操作符指定返回的键。省略时默认全部返回。_id是一直都返回的,如果不需要返回,必须显式指定不返回。

栗子:

// 返回item和qty字段,其他全部不返回
db.getCollection("student").find( {a:{$type:"string"}},{ item: 1, qty: 1, _id:0 } ) 

 

 

10、格式化查询结果

// 将文档格式化输出,在shell中有用,但是在可视化工具中用途不大
db.getCollection("student").find({}).pretty();  

 

 

11、更新文档:

// 有两种方式:update和save
1:db.getCollection("student").update(  
  {<query>},
  {<update>},
  {
    upsert: <boolean>,
    multi: <boolean>,
    writeConcern: <document>
   }
);
2:db.getCollection("student").save({document});

 

说明:

  • save()以文档中_id为条件进行查询,如果存在,则整个文档进行更新。

  • update更灵活,为查询条件,为更新的字段,剩下三个参数。

  • :查询条件,和find()中的查询条件写法一样。

  • : 更新的操作符,用于细化更新字段,如$set、$inc等。

  •  upsert:可选。如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。相当于update + insert。

  • multi:可选。mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。

  • writeConcern:可选,抛出异常的级别。(个人感觉没啥卵用)

 MongoDB学习笔记_第16张图片

db.col.update({'title':'MongoDB 教程'},{$set:{'title':'MongoDB'}})

 

 

 

update(更新的操作符)说明:

  • $inc

  { $inc : { field : value } }。意思对一个数字字段field增加value

// 表示给_id为123的文档的price字段增加5
db.col.update({_id:123},{$inc:{price:5}})

【注意】value可以为整数也可以为负数。

  • $set

{ $set : { field : value } }。赋值语句

// 相当于SQL中set语句
db.col.update(
  {
    title:1.0,
    title:{$type:1}
  },
  {
    $set:{title:"张",aa:"aa"},
    $inc:{bb:9}
  }
);

 

 

  • $unset

    { $unset : { field : 任意内容} }。就是删除field字段

db.getCollection('account').update(    {title:"张"},    {$unset:{aa:1,bb:1}})

 

 

  • $push

    { $push : { field : value } }。把value追加到field里面去,field一定要是数组类型才行,如果field不存在,会新增一个数组类型加进去。

db.getCollection('account').update(    {title:"张"},    {$push:{tags:"mysql"} })
 

 

  • $pushAll

    { $pushAll : { field : value_array } }。将数组中的每一项,追加多个值到一个数组字段内【高版本的MongoDB中没有这个命令,反正我的没有】

db.getCollection('account').update(    {"userid":3},    {$pushAll:{"name":["N1","N2"]}} )

 

 

  • $addToSet

    { $addToSet : { field : value } }。增加一个值到数组内,而且只有当这个值不在数组内才增加。

db.getCollection('account').update(    {title:"张"},    {$addToSet:{tags:"222"}})

 

 

  • $pop

    删除最后一个值:{ $pop : { field : 1 } }
    删除第一个值:{ $pop : { field : -1 } }

    注意:值只能是1或-1,否则报错。

db.getCollection('account').update({title:"张"},{$pop:{tags:1}})

 

 

  • $pull

    $pull : { field : value } }。从数组field内删除一个等于value值。

db.getCollection('account').update(    {title:"张"},    {$pull:{tags:"333"}})

 

 

  • $pullAll

    { $pullAll : { field : value_array } }。可以一次删除数组内的多个值。

db.getCollection('account').update(    {title:"张"},    {$pullAll:{tags:["222","mysql"]}})

 

 

  • $ 操作符

    $美元符号是在查询数组时才用的,作为定位符,匹配第一个符合查询条件的值的位置

 

说明:

 MongoDB学习笔记_第17张图片

 MongoDB学习笔记_第18张图片

 MongoDB学习笔记_第19张图片

 MongoDB学习笔记_第20张图片

 

12、删除文档

db.collection.remove(  
  <query>,
  {
    justOne: <boolean>,
    writeConcern: <document>
  }
);

 

说明:

  • justOne:(可选)如果设为 true 或 1,则只删除一个文档,如果不设置该参数,或使用默认值 false,则删除所有匹配条件的文档。

 

注意:在写参数时,以下两种方式都是可以的,第一种方法可以针对性的指定参数,但是必须写参数名。第二种方法可以省略参数名,但是必须把前面的参数值也填写完整,而且顺序不能错。

1:db.getCollection('account').remove(    {title:"MongoDB 教程"},    {justOne:1});
2:db.getCollection('account').remove({title:1},true);

 

 

13、限制文档输出数量:

db.getCollection('account').find().limit(数量);

 

 

14、输出文档时跳过前面的文档

db.getCollection('account').find().skip(数量);

 

提示:

    limit和skip组合起来就可以实现分页了。

// 先由skip跳过前面没用的记录,再用limit限定当前页面显示的内容
db.getCollection('account').find().skip(数量).limit(数量);

 

 

15、排序

db.getCollection('account').sort({title:-1,likes:1})

 

说明:

  • 按顺序进行排序,如例子中先按title排序,相同title的再按likes排序。

  • -1代表从大到小,desc,倒序。

  • 1代表从小到大,asc,顺序。

 

 16、索引

   和普通关系型数据库一样,建立索引可以提升数据查找的速度

db.collection.createIndex(keys, options)
db.col.createIndex({"title":1})

 

 keys对象参数为1表示正序建立索引,-1表示逆序建立索引。如果添加多个属性为联合索引。

 MongoDB学习笔记_第21张图片

 

 

 红色圈圈圈出来的是我个人认为比较常用的

 

其他索引操作:

  • 查看集合索引
db.col.getIndexes()

 

  • 查看集合索引大小
db.col.totalIndexSize()

 

  • 删除集合所有索引
db.col.dropIndexes()

 

  • 删除集合指定索引
db.col.dropIndex("索引名称")

 

  • 设置定时删除任务(利用了expireAfterSeconds)

  利用 TTL 集合对存储的数据进行失效时间设置:经过指定的时间段后或在指定的时间点过期,MongoDB 独立线程去清除数据。

// 例如在数据记录中 createDate 为日期类型之后180删除
db.col.createIndex({"createDate": 1},{expireAfterSeconds: 180})

 

   如果expireAfterSeconds的值为0,则以索引字段的值的实际时间去进行删除。

   其他注意事项:

  • 索引关键字段必须是 Date 类型。
  • 非立即执行:扫描 Document 过期数据并删除是独立线程执行,默认 60s 扫描一次,删除也不一定是立即删除成功。
  • 单字段索引,混合索引不支持。

 

 

 

 

 

08

数据库备份与恢复

  1、备份

MongoDB学习笔记_第22张图片

 

 

 

  2、恢复

MongoDB学习笔记_第23张图片

 

 

 

09

数据库性能监控

  【注意】在使用身份验证模式下,需要使用root权限来查看数据库性能。一般用户没有这个能力,无法打开性能监控。

MongoDB学习笔记_第24张图片

 

 

 

 

输出字段解析:

 

 

   MongoDB学习笔记_第25张图片

 

 

 

 

MongoDB学习笔记_第26张图片

 

 

MongoDB学习笔记_第27张图片

 

 MongoDB学习笔记_第28张图片

 

 

 

10

数据库高级查询

  前面介绍的内容都是数据基本的增删改查,但是NoSQL出现了一个多个集合之间数据组织的问题。NoSQL不像关系型数据库,通过关系来实现多数据直接的结合。要想实现多文档,多集合的管理数据,就要使用应用层来回查询。使用这种方式将会消耗大量的网络数据,不利于数据库操作的效率。

  但是MongoDB作为最像关系型数据库的非关系型数据库,也为我们提供了多集合联合查询的功能

 

1、聚合通道  

  MongoDB中聚合的方法使用aggregate()。聚合就是可以对数据查询进行多次过滤操作,以达到复杂查询的目的。聚合查询函数接收一个数组,数组里面是若干个对象,每个对象就是一次查询的步骤。前一个查询的查询结果,作为后一个查询的筛选内容。

  这种聚合通道,和Java8中的集合的stream流操作很类似。

db.getCollection("student").aggregate(
[
    {
        "$match" : {
            "age" : {
                "$gt" : 20.0
            }
        }
    },
    {
        "$lookup" : {
            "from" : "room",
            "localField" : "class",
            "foreignField" : "name",
            "as" : "num"
        }
    },
    {
        "$unwind" : {
            "path" : "$num",
            "includeArrayIndex" : "l",
            "preserveNullAndEmptyArrays" : false
        }
    },
    {
        "$project" : {
            "num.name" : 1.0
        }
    },
    {
        "$count" : "cou"
    }
]);

 

MongoDB学习笔记_第29张图片

MongoDB学习笔记_第30张图片

 

 

 下面我只详细说明部分操作符:

MongoDB学习笔记_第31张图片

 

 MongoDB学习笔记_第32张图片

 

 MongoDB学习笔记_第33张图片

 

 

 

 MongoDB学习笔记_第34张图片

 

 MongoDB学习笔记_第35张图片

 

 MongoDB学习笔记_第36张图片

 

 MongoDB学习笔记_第37张图片

 

 MongoDB学习笔记_第38张图片

 

 MongoDB学习笔记_第39张图片

 

 MongoDB学习笔记_第40张图片

 

 

 MongoDB学习笔记_第41张图片

 

 MongoDB学习笔记_第42张图片

 

 MongoDB学习笔记_第43张图片

 

 MongoDB学习笔记_第44张图片

 

 MongoDB学习笔记_第45张图片

 

 MongoDB学习笔记_第46张图片

 

 

  一些随便的查询:

  注意:如果查询中用到内嵌文档的属性,要整个字段名用引号括起来,包括根文档的。例如查询13

 MongoDB学习笔记_第47张图片

 

 

 

13

Java连接操作MongoDB

  有三种连接方式,官方提供的jdbc连接(mongo-java-driver)和 spring-boot-starter-data-mongodb ,以及spring-data-jpa(我不喜欢用jpa,所以这里不介绍)

1、mongo-java-driver

步骤一:添加jar包

<dependency>
    <groupId>org.mongodbgroupId>
    <artifactId>mongo-java-driverartifactId>
    <version>3.12.2version>
dependency>    

骤二:连接到 mongodb 服务(MongoDB连接有很多的重载方法,这里只给出几种,其他自己去看MongoClient)

// 连接到 mongodb 服务
1、MongoClient mongoClient = new MongoClient( "localhost"  );  // 用指定主机的默认端口连接

2、MongoClient mongoClient = new MongoClient( "localhost" , 27017 );  // 用指定主机指定端口连接

3、MongoClientOptions.Builder builder = new MongoClientOptions.Builder();
  MongoClient mongoClient = new MongoClient( "localhost" , builder );  // 填写相关连接配置

4、
List serverAddressList = new ArrayList<>(2);

   serverAddressList.add(new ServerAddress("192.168.1.117", 27015));
   serverAddressList.add(new ServerAddress("192.168.1.116", 27016));
   MongoClient mongoClient = new MongoClient( serverAddressList );    // 连接多个MongoDB

  5、MongoClient mongoClient = new MongoClient( new MongoClientURI("mongodb://root:root@localhost:27017") );    // 使用连接地址

 

  6、MongoClient mongoClient = new MongoClient( new ServerAddress("localhost",27017)    // 使用密码

        ,MongoCredential.createScramSha1Credential("root", "admin", "root".toCharArray())

        ,MongoClientOptions.builder().build());

 

   步骤三:选择数据库

MongoDatabase mongoDatabase = mongoClient.getDatabase("test"); 

 

 注意:如果数据库不存在,插入一条数据后,会自动创建数据库

 

 步骤四:选择集合

MongoCollection collection = mongoDatabase.getCollection("account");

 

 注意:如果集合不存在,插入一条数据后,会自动创建集合

 

步骤五:常规操作,如新增,修改,删除,查找,统计

// 插入
Document document = new Document("id", "123")
        .append("name", "微三云")
        .append("date", new Date());
collection.insertOne(document);

 

 MongoDB学习笔记_第48张图片

 

 

   public class Document implements Map, Serializable, Bson

 Document 对象继承自map和Bson,Bson这个接口在MongoDB的API中很常见。用到Bson的地方基本都可以丢个Document进去。

 Document的创建方式也有很多:

MongoDB学习笔记_第49张图片

 

   MongoDB学习笔记_第50张图片

 

 

// 删除
DeleteResult deleteOne = collection.deleteOne(Document.parse("{id:3456}"));  // 删除一条
DeleteResult deleteMany
= collection.deleteMany(Filters.eq("name", "张三"));   // 删除多条
System.err.println(deleteMany.getDeletedCount());  // 查看删除的结果

 MongoDB学习笔记_第51张图片

 

 

 

// 更新
collection.findOneAndUpdate(Filters.eq("name", "张三"), Document.parse("{$set:{name:\"李阳\"}}"));  // 这个命令是只更新一条记录

collection.updateMany(Filters.eq("id", 3456), Document.parse("{$set:{name:\"李\"}}"));  // 更新多条

collection.updateOne(Filters.eq("id", 3456), Document.parse("{$set:{name:\"李\"}}"));  // 更新找到的第一条,默认顺序是数据库文档顺序

 MongoDB学习笔记_第52张图片

 MongoDB学习笔记_第53张图片

 

// 查找
FindIterable find = collection.find(Filters.eq("id", 3456)); MongoCursor iterator = find.iterator(); while(iterator.hasNext()) { Document next = iterator.next(); System.err.println(next); }

 

 MongoDB学习笔记_第54张图片

 

 

 还有很多其他方法:

MongoDB学习笔记_第55张图片

   MongoDB学习笔记_第56张图片

 

   MongoDB学习笔记_第57张图片

 MongoDB学习笔记_第58张图片

 

 

 

 

   2、spring-boot-starter-data-mongodb

 其实这个是spring在MongoDB-Java-driver上进行封装的,能够自动返回Java对象

 使用步骤:

   步骤一:搭好spring boot环境,加入spring-boot-starter-data-mongodb启动器依赖

   MongoDB学习笔记_第59张图片

 

 

 

  步骤二:导入项目

  MongoDB学习笔记_第60张图片

 

 

 

  步骤三:添加配置,properties配置(yml配置也行,自己整理格式)

spring.data.mongodb.host=localhost
spring.data.mongodb.port=27017
spring.data.mongodb.database=myMongodb
# 默认没有账号密码
spring.data.mongodb.username=hongcheng
spring.data.mongodb.password=hongcheng

 

 

  步骤四:注入MongoTemplate(常规操作)或者GridFsTemplate(基于MongoDB来持久存储文件,后面引用另外一位老哥的文章介绍)

@Autowired
private MongoTemplate mongoTemplate;

 

 

  步骤五:写代码

MongoDB学习笔记_第61张图片

 

 

 MongoDB学习笔记_第62张图片

 

 

 

MongoTemplate里面有很多方法,基本实现了增删改查的全部功能。而且也提供了直接执行json命令的方法。可以说就算你不会用这个东西,只要你会写MongoDB的基础命令,就能用了。

MongoDB学习笔记_第63张图片

 

 

 

public Document executeCommand(final String jsonCommand) ;

public Document executeCommand(final Document command);

public Document executeCommand(Document command, @Nullable ReadPreference readPreference);

public void executeQuery(Query query, String collectionName, DocumentCallbackHandler dch) ;

public T execute(DbCallback action) {

    Assert.notNull(action, "DbCallback must not be null!");

  try {
    MongoDatabase db = prepareDatabase(this.doGetDatabase());
    return action.doInDB(db);
  } catch (RuntimeException e) {
    throw potentiallyConvertRuntimeException(e, exceptionTranslator);
  }
}

  public T execute(Class entityClass, CollectionCallback callback);

 

  public T execute(String collectionName, CollectionCallback callback) {

    Assert.notNull(collectionName, "CollectionName must not be null!");
    Assert.notNull(callback, "CollectionCallback must not be null!");

    try {
      MongoCollection collection = getAndPrepareCollection(doGetDatabase(), collectionName);
      return callback.doInCollection(collection);
    } catch (RuntimeException e) {
      throw potentiallyConvertRuntimeException(e, exceptionTranslator);
    }
  }

 

MongoDB学习笔记_第64张图片

 

 

 

 

 MongoDB学习笔记_第65张图片

 

 

 

 

 MongoDB学习笔记_第66张图片

 

 

 MongoDB学习笔记_第67张图片

 

 

 MongoDB学习笔记_第68张图片

 

 

 MongoDB学习笔记_第69张图片

 

 

 

 

 

 

 MongoDB学习笔记_第70张图片

MongoDB学习笔记_第71张图片

 MongoDB学习笔记_第72张图片

 

 

 

 

 

 

MongoDB学习笔记_第73张图片

 

 

 

 

 

MongoDB学习笔记_第74张图片

 

 

 

 

 

MongoDB学习笔记_第75张图片

 

 

 MongoDB学习笔记_第76张图片

 

 

 

 

 

这里我放另外一个大哥的文档,介绍怎么使用aggregate:https://blog.csdn.net/C18298182575/article/details/100698885

 

 

 

 MongoDB学习笔记_第77张图片

 

 

 MongoDB学习笔记_第78张图片

 

 

 MongoDB学习笔记_第79张图片

 

 MongoDB学习笔记_第80张图片

 

 

14

MapReduce操作

 

   这里再讲下MapReduce操作,在借用另外一个大哥的文章:https://www.cnblogs.com/chenpingzhao/p/7913247.html

 

 

MongoDB学习笔记_第81张图片

 

 MongoDB学习笔记_第82张图片

  MongoDB学习笔记_第83张图片

MongoDB学习笔记_第84张图片

 

 MongoDB学习笔记_第85张图片

 

 

 MongoDB学习笔记_第86张图片

 

 

 MongoDB学习笔记_第87张图片

 

 

 MongoDB学习笔记_第88张图片

 

 

 

 

 

 15

 Spring Boot使用mongoGridFS模块

   再来一个老哥的文档(以下内容来自该文档,可直接前往查看):

  https://www.cnblogs.com/mengrennwpu/p/8849551.html

  

 Spring Boot使用mongoGridFS模块
1. GridFS简介
  GridFSMongo的一个子模块,使用GridFS可以基于MongoDB来持久存储文件。并且支持分布式应用(文件分布存储和读取)。作为MongoDB中二进制数据存储在数据库中的解决方案,通常用来处理大文件,对于MongoDBBSON格式的数据(文档)存储有尺寸限制,最大为16M。但是在实际系统开发中,上传
的图片或者文件可能尺寸会很大,此时我们可以借用GridFS来辅助管理这些文件。
  GridFS不是MongoDB自身特性,只是一种将大型文件存储在MongoDB的文件规范,所有官方支持的驱动均实现了GridFS规范。GridFS制定大文件在数据库中如何处理,通过开发语言驱动来完成、通过API接口来存储检索大文件。

2. GridFS使用场景
  (1) 如果您的文件系统在一个目录中存储的文件的数量有限,你可以使用GridFS存储尽可能多的文件。
  (2) 当你想访问大型文件的部分信息,却不想加载整个文件到内存时,您可以使用GridFS存储文件,并读取文件部分信息,而不需要加载整个文件到内存。
  (3) 当你想让你的文件和元数据自动同步并部署在多个系统和设施,你可以使用GridFS实现分布式文件存储。

3. GridFS存储原理
  GridFS使用两个集合(collection)存储文件。一个集合是chunks, 用于存储文件内容的二进制数据;一个集合是files,用于存储文件的元数据。
  GridFS会将两个集合放在一个普通的buket中,并且这两个集合使用buket的名字作为前缀。MongoDBGridFs默认使用fs命名的buket存放两个文件集合。因此存储文件的两个集合分别会命名为集合fs.files ,集合fs.chunks
  当然也可以定义不同的buket名字,甚至在一个数据库中定义多个bukets,但所有的集合的名字都不得超过mongoDB命名空间的限制。
  MongoDB集合的命名包括了数据库名字与集合名字,会将数据库名与集合名通过“.”分隔(eg:.)。而且命名的最大长度不得超过120bytes
  当把一个文件存储到GridFS时,如果文件大于chunksize (每个chunk块大小为256KB),会先将文件按照chunk的大小分割成多个chunk块,最终将chunk块的信息存储在fs.chunks集合的多个文档中。然后将文件信息存储在fs.files集合的唯一一份文档中。其中fs.chunks集合中多个文档中的file_id字段
对应fs.files集中文档”_id”字段。
  读文件时,先根据查询条件在files集合中找到对应的文档,同时得到“_id”字段,再根据“_id”chunks集合中查询所有“files_id”等于“_id”的文档。最后根“n”字段顺序读取chunk“data”字段数据,还原文件。

4. 存储过程
  fs.files 集合存储文件的元数据,以类json格式文档形式存储。每在GridFS存储一个文件,则会在fs.files集合中对应生成一个文档。
  fs.files集合中文档的存储内容如下:

 MongoDB学习笔记_第89张图片

 

 

  fs.chunks 集合存储文件文件内容的二进制数据,以类json格式文档形式存储。每在GridFS存储一个文件,GridFS就会将文件内容按照chunksize大小(chunk容量为256k)分成多个文件块,然后将文件块按照类json格式存在.chunks集合中,每个文件块对应fs.chunk集合中一个文档。一个存储文件会对应一到多个chunk文档。
  fs.chunks集合中文档的存储内容如下:

 MongoDB学习笔记_第90张图片

 

 

   为了提高检索速度 MongoDBGridFS的两个集合建立了索引。fs.files集合使用是“filename”“uploadDate” 字段作为唯一、复合索引。fs.chunk集合使用的是“files_id”“n”字段作为唯一、复合索引。


5. 注意事项

(1) GridFs不会自动处理md5值相同的文件,也就是说,同一个文件进行两次put命令,将会在GridFS中对应两个不同的存储,对于存储来说,这是一种浪费。对于md5相同的文件,如果想要在GridFS中只有一个存储,需要通过API进行扩展处理。

(2) MongoDB 不会释放已经占用的硬盘空间。即使删除db中的集合 MongoDB也不会释放磁盘空间。同样,如果使用GridFS存储文件,从GridFS存储中删除无用的垃圾文件,MongoDB依然不会释放磁盘空间的。这会造成磁盘一直在消耗,而无法回收利用的问题。如何释放磁盘空间?
 

 (1) 可以通过修复数据库来回收磁盘空间,即在mongo shell中运行db.repairDatabase()命令或者db.runCommand({ repairDatabase: 1 })命令。(此命令执行比较慢)。
使用通过修复数据库方法回收磁盘时需要注意,待修复磁盘的剩余空间必须大于等于存储数据集占用空间加上2G,否则无法完成修复。因此使用GridFS大量存储文件必须提前考虑设计磁盘回收方案,以解决mongoDB磁盘回收问题。


  (2) 使用dump & restore方式,即先删除mongoDB数据库中需要清除的数据,然后使用mongodump备份数据库。备份完成后,删除MongoDB的数据库,使用Mongorestore工具恢复备份数据到数据库。当使用db.repairDatabase()命令没有足够的磁盘剩余空间时,可以采用dump & restore方式回收磁盘资源。如果MongoDB是副本集模式,dump &
restore方式可以做到对外持续服务,在不影响MongoDB正常使用下回收磁盘资源。

 

 6. 代码示例

 MongoDB学习笔记_第91张图片

 

 MongoDB学习笔记_第92张图片

 

 

 

 

 花了这么久,总算结束了,参考了很多人的文章,有些没有直接写出来,先说声抱歉了,毕竟有些我自己都找不到文章地址了。

 如果这篇文章对你有用,给我点个赞好么。

 参考文章:

https://blog.csdn.net/konghouy/article/details/90146763

https://www.jianshu.com/p/72fc4409936c

https://blog.csdn.net/C18298182575/article/details/100698885

https://www.cnblogs.com/chenpingzhao/p/7913247.html

https://www.runoob.com/mongodb/mongodb-tutorial.html

https://www.mongodb.org.cn/   

 

 

你可能感兴趣的:(MongoDB学习笔记)