本博客java云同桌学习系列,旨在记录本人学习java的过程,并与大家分享,对于想学习java的同学,我希望这个系列能够鼓励大家一同与我学习java,成为“云同桌”。

每月预计保持更新数量三章起,每章都会从整体框架入手,介绍章节所涉及的重要知识点及相关练习题,并会设置推荐学习时间,每篇博客涉及到的点都会在开篇目录进行总览。(博客中所有高亮部分表示是面试题进阶考点)


MongoDB也是属于NoSQL型数据库,常用于一些网站的实时数据处理,插入、查询效率较高同时兼容性好。

mongoDB

  • 1. mongoDB概述
  • 2. mongoDB安装
  • 3. mongoDB常用指令
  • 4.Java连接mongoDB数据库
  • 5.mongoDB集群

学习时间:一周
学习建议:mongoDB也是主流的NoSQL数据库,需要进行一定的了解,是成为高级工程师必经的一步

1. mongoDB概述

mongoDB:是一个基于分布式文件存储、介于关系数据库和非关系数据库之间、json-bson格式、由C++语言编写的NoSQL数据库

特点:

  • 面向BSON(Binary JSON)格式文档存储数据
  • 面向集合存储,易存储对象类型的数据
  • 高性能、易部署、易使用、易扩展
  • 支持高效动态查询
  • 支持多种开发语言驱动
  • *支持完全索引,包含内部对象

应用场景:

  1. 实时数据快速查询处理
  2. 日志文件记录
  3. 地理位置数据存储、查询

不适用场景:

  1. 要求高度事务性的系统。
  2. 复杂的跨文档(表)级联查询。

2. mongoDB安装

建议安装在Linux系统进行,官方最新版安装包

  1. 将tar包解压到相应位置,然后进入其中的bin目录,新建一个mongodb.conf文件,内容为:

    dbpath = /home/fb/mongoDB/mongoDB_data # Data file path
    logpath = /home/fb/mongoDB/mongoDB_logs/mongodb.log # Log file path
    port = 27017 #
    fork = true #
    

    第一个为提前自定义的一个存放数据文件的文件夹
    第二个为提前自定义的一个存放日志的日志文件
    第三个port是mongoDB数据库默认的端口,mongoDB默认端口27017

  2. 然后启动mongoDB服务器并更新配置文件:./mongod -f mongodb.conf

    fb@fb-virtual-machine:~/mongoDB/mongoDB/mongodb-linux-x86_64-ubuntu1804-4.4.2/bin$ ./mongod -f mongodb.conf
    about to fork child process, waiting until server is ready for connections.
    forked process: 31844
    child process started successfully, parent exiting
    
  3. 然后启动客户端:./mongo

    fb@fb-virtual-machine:~/mongoDB/mongoDB/mongodb-linux-x86_64-ubuntu1804-4.4.2/bin$ ./mongo
    MongoDB shell version v4.4.2
    connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
    Implicit session: session { "id" : UUID("425f3c1f-bf45-4126-938a-35603dbc5158") }
    MongoDB server version: 4.4.2
    Welcome to the MongoDB shell.
    For interactive help, type "help".
    For more comprehensive documentation, seehttps://docs.mongodb.com/
    Questions? Try the MongoDB Developer Community Forumshttps://community.mongodb.com
    ---
    The server generated these startup warnings when booting: 2021-01-01T18:06:44.214+08:00: Using the XFS filesystem is strongly recommended with the WiredTiger storage engine. See http://dochub.mongodb.org/core/prodnotes-filesystem2021-01-01T18:06:44.937+08:00: Access control is not enabled for the database. Read and write access to data and configuration is unrestricted2021-01-01T18:06:44.937+08:00: This server is bound to localhost. Remote systems will be unable to connect to this server. Start the server with --bind_ip <address> to specify which IP addresses it should serve responses from, or with --bind_ip_all to bind to all interfaces. If this behavior is desired, start the server with --bind_ip 127.0.0.1 to disable this warning2021-01-01T18:06:44.937+08:00: Soft rlimits too low2021-01-01T18:06:44.937+08:00:         currentValue: 10242021-01-01T18:06:44.937+08:00:         recommendedMinimum: 64000
    ---
    ---Enable MongoDB's free cloud-based monitoring service, which will then receive and displaymetrics about your deployment (disk utilization, CPU, operation statistics, etc).The monitoring data will be available on a MongoDB website with a unique URL accessible to youand anyone you share the URL with. MongoDB may use this information to make productimprovements and to suggest MongoDB products and deployment options to you.To enable free monitoring, run the following command: db.enableFreeMonitoring()To permanently disable this reminder, run the following command: db.disableFreeMonitoring()
    ---
    > 
  4. 把mongoDB配置到环境变量中

    修改/etc/profile文件:

    export mongodb_home=/home/fb/mongoDB/mongoDB/mongodb-linux-x86_64-ubuntu1804-4.4.2
    export PATH=$PATH:$mongodb_home/bin
    

    对于已有其他环境变量配置了PATH,添加新的PATH路径,需要用冒号:隔开添加

    更新环境变量:source /etc/profile

    然后就可以在任意位置,使用mongo来启动mongoDB客户端了

3. mongoDB常用指令

详情请查看:菜鸟编程之mongoDB

首先,mongoDB中某些术语与常用叫法不同:

mongoDB中是以集合的结构进行存储,以文档的形式进行保存,每个文档中都有一个默认的"_id"作为主键,为调用方便,建议开发者自己设置

{"_id" : ObjectId()}

ObjectId是一个12字节(24个十六进制数字)的存储空间,ObjectId的12字节数据组织方式如下:0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11时间戳      |  机器码    |  PID  |  计数器{"_id" : ObjectId("5444cce6aef53b0f343e2b9b")}
/* 上面ObjectId各位字符含义如下 */
//5444cce6,第0〜3字节(第1〜8位)为时间戳
//aef53b,第4〜6字节(第9〜14位)为机器码
//0f34,第7〜8字节(第15〜18位)为进程ID
//3e2b9b,第9〜11字节(第19〜24位)为自增计数器

在存储时,以键值对的形式进行存储,值可以为多种形式:

  • {“x” : “123@qq.com”} UTF-8编码字符
  • {“x” : new Date()} 时间戳形式
  • {“x” : /kaikeba/i} 正则表达式
  • {“x” : [“kaikeba”, “kaikeba.com”]} 数组形式
  • {“x” : {“kaikeba” : “kaikeba.com”}} 嵌套形式
    mongoDB文档大小有限制,故建议使用嵌套的形式来存储数据,也便于查询
  • {“x” : function(){ /这里是一段JavaScript代码/}}

mongoDB是由C++语言编写的,但是大约20%的API交互是由js编写的,故大部分交互命令和js命令极为相似

数据库级别的操作:

  • 连接数据库mongo ip地址 [:端口号]如果需要远程连接mongoDB,需要更改mongodb.conf文件中的bind_ip=绑定IP
  • 查看数据库 show dbs
  • 查看当前数据库 db,默认初始所在数据库为test

mongoDB中数据库的创建机制类似于Windows10的记事本,会创建一个临时的文件,然后有数据才会进行保存

  • 切换/创建数据库 use 数据库名 (可以直接创建数据库,但只有添加数据后,show dbs才能看到该数据库)
  • 查看当前数据库下所有的集合(表)show collections
  • 删除当前数据库 db.dropDatabase(),注意使用"."连接

集合(表)表级别操作:

命令 描述
>db.createCollection(“集合名”) 创建集合
>db.集合名.drop() 删除集合
>db.集合名.insert({“key”:value,“key”:value}) 插入数据
>db.集合名.save({“key”:value,“key”:value}) 插入数据
>db.集合名.find() 查询所有数据
> db
test
> db.createCollection("test1")
{ "ok" : 1 }
> db.test1.insert({"key":"hello mongoDB!"})
WriteResult({ "nInserted" : 1 })
> db.test1.find()
{ "_id" : ObjectId("5ff3cf82fa49b7fe20e98bb9"), "key" : "hello mongoDB!" }
#主键_id是自动生成的,上面有提到

之前我们说mongoDB的查询功能非常的卓越,接下来我们就来看一下find()的细致用法

命令 描述
>db.集合名.find({“age”:26}) 查询等值关系
>db.集合名.find({age : {$gt : 100}}) 查询age > 100
>db.集合名.find({age : {$gte : 100}}) 查询age >= 100
>db.集合名.find({age : {$lt : 150}}) 查询age < 150
>db.集合名.find({age : {$lte : 150}}) 查询age <= 150
>db.集合名.find({age : {$lt : 200, $gt : 100}}) 查询 100 < age < 200
>db.集合名.find({age : {$ne : 50}}) 查询 age != 50

对于AND关系,可以传入多个关系然后用逗号隔开:

db.集合名.find({“by”:“java”, “title”:“MongoDB学习”})

对于OR关系,需要使用$or关键字:

db.集合名.find({$or:[{“by”:“java”},{“title”: “MongoDB学习”}]})

为了使查询出的数据可读性更强,可以使用pretty()以JSON格式显示:

> db.col.find().pretty()
{"_id" : ObjectId("56064f89ade2f21f36b03136"),"title" : "MongoDB","description" : "MongoDB 是一个 Nosql 数据库","by" : "菜鸟教程","url" : "http://www.runoob.com","tags" : ["mongodb","database","NoSQL"],"likes" : 100
}

对于删除文档数据,使用>db.collectionName.remove({})

//条件删除:remove({key:value})
//删除满足条件的一条数据:remove({key:value},1)`

对于只需要显示某些字段

db.集合名.find({},{name:1,age:1})
// 显示name 和 age 字段,默认显示_id

对于指定字段去重

db.集合名.distinct(‘字段名’)

对于结果排序显示

db.集合名.find().sort({字段名:1}) //升序
db.集合名.find().sort({字段名:-1}) //降序

对于数量进行统计

db.集合名.find().count()

对于限定条数查询,以及跳过限定条数

db.集合名.find().limit(number)
db.集合名.find().limit(number).skip(number)


文档(行)层级:

更新已存在的文档:

db.collection.update(<query>,<update>,{upsert: <boolean>,multi: <boolean>,writeConcern: <document>}
)
/*
query : update的查询条件,类似sql update查询内where后面的。
update : update的对象和一些更新的操作符(如$,$inc...)等,也可以理解为sql update查询内set后面的
upsert : 可选,这个参数的意思是,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。
multi : 可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。
writeConcern :可选,抛出异常的级别。
*/

对于已存在的文档,想要新添加字段,需要使用$set 关键字

> db.test1.update({},{$set:{"key4":"hello mongoDB4"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

此外还有一些需要注意的关键字,详情查看:mongoDB之Update

关键字 描述
$inc 操作符$inc可以为指定的键执行(原子)更新操作,如果字段存在,就将该值增加给定的增量,如果该字段不存在,就创建该字段。
$set 设置字段值,可以使用$set操作符将某个字段设置为指定值。
$unset 删除指定字段
$rename 重命名字段名称
$push 在指定字段中添加某个值

备份与恢复数据指令:

  • 备份数据mongodump -h dbhost -d dbname -o dbdirectory

    • -h 指定mongoDB所在服务器ip
    • -d 指定要备份的数据库名
    • -o 指定备份后数据存放位置
  • 恢复/导入数据 mongorestore -h <hostname><:port> -d dbname <path>
    • -h 指定mongoDB所在服务器ip
    • -d 指定要导入到的目标数据库名 (可以与原数据库名不一致)

4.Java连接mongoDB数据库

首先,需要先添加依赖包mongodb-java-driver3.12.7,Maven坐标如下:

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

与mongodb进行连接,通过mongoClient类构造方法传入ip地址和端口号, 获取数据库操作对象,集合操作对象,调用相关的函数(函数名和mongoDB指令一致)

//连接到 mongodb 服务
MongoClient mongoClient = new MongoClient("192.168.188.131", 27017);
//连接到数据库
MongoDatabase mongoDatabase = mongoClient.getDatabase("test");
//创建数据库集合
mongoDatabase.createCollection("testConnection");
//获得集合
MongoCollection<Document> collection = mongoDatabase.getCollection("testConnection");
//新增数据并插入该集合
Document document = new Document("test", "this connection test is success!");
collection.insertOne(document);
//插入多行时,将document对象添加到List集合中,调取insertMany()
//获得所有文档,打印输出数据
FindIterable<Document> documents = collection.find();
MongoCursor<Document> iterator = documents.iterator();
while (iterator.hasNext()) {System.out.println(iterator.next());
}/*输出:
Document{{_id=5ff4415b0191926b0cc84004, test=this connection test is success!}}
*/

5.mongoDB集群

同样的,和redis集群出发点相同,mongoDB集群也是为了提高可靠性、高效性而建立

集群中共同管理一个数据仓库,主(primary)可以进行读写操作,从(secondary)始终保持数据同步,默认不允许进行读写(需rs.slaveOK())

并且当主数据库在超过配置的周期(默认为 10 秒)内未与该组的其他成员通信时,符合条件的辅助服务器将要求选择将其自身指定为新的主服务器。集群试图完成新的初选并恢复正常操作。

搭建步骤:

  1. 准备好三个mongoDB服务器,修改他们的mongodb.conf配置文件,不同的ip或端口,赋予同一个集群名称,比如rep1

    #复制集名称
    replSet=rep1
    
  2. 登陆任意一台执行初始化操作,建立集群之间的关系

    > rs.initiate({_id:'rep1',members:[{_id:1,host:'192.168.188.131:27018'},{_id:2,host:'192.168.188.131:27019'},{_id:3,host:'192.168.188.131:27020'}]})
    {"ok" : 1,"$clusterTime" : {"clusterTime" : Timestamp(1609847584, 1),"signature" : {"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),"keyId" : NumberLong(0)}},"operationTime" : Timestamp(1609847584, 1)
    }
  3. 测试查看集群状态rs.status()

    rep1:SECONDARY> rs.status()
    {"set" : "rep1","date" : ISODate("2021-01-05T11:53:23.244Z"),"myState" : 1,"term" : NumberLong(1),"syncSourceHost" : "","syncSourceId" : -1,"heartbeatIntervalMillis" : NumberLong(2000),"majorityVoteCount" : 2,"writeMajorityCount" : 2,"votingMembersCount" : 3,"writableVotingMembersCount" : 3,"optimes" : {"lastCommittedOpTime" : {"ts" : Timestamp(1609847597, 1),"t" : NumberLong(1)},"lastCommittedWallTime" : ISODate("2021-01-05T11:53:17.244Z"),"readConcernMajorityOpTime" : {"ts" : Timestamp(1609847597, 1),"t" : NumberLong(1)},"readConcernMajorityWallTime" : ISODate("2021-01-05T11:53:17.244Z"),"appliedOpTime" : {"ts" : Timestamp(1609847597, 1),"t" : NumberLong(1)},"durableOpTime" : {"ts" : Timestamp(1609847597, 1),"t" : NumberLong(1)},"lastAppliedWallTime" : ISODate("2021-01-05T11:53:17.244Z"),"lastDurableWallTime" : ISODate("2021-01-05T11:53:17.244Z")},"lastStableRecoveryTimestamp" : Timestamp(1609847595, 3),"electionCandidateMetrics" : {"lastElectionReason" : "electionTimeout","lastElectionDate" : ISODate("2021-01-05T11:53:15.813Z"),"electionTerm" : NumberLong(1),"lastCommittedOpTimeAtElection" : {"ts" : Timestamp(0, 0),"t" : NumberLong(-1)},"lastSeenOpTimeAtElection" : {"ts" : Timestamp(1609847584, 1),"t" : NumberLong(-1)},"numVotesNeeded" : 2,"priorityAtElection" : 1,"electionTimeoutMillis" : NumberLong(10000),"numCatchUpOps" : NumberLong(0),"newTermStartDate" : ISODate("2021-01-05T11:53:15.845Z"),"wMajorityWriteAvailabilityDate" : ISODate("2021-01-05T11:53:16.996Z")},"members" : [{"_id" : 1,"name" : "192.168.188.131:27018","health" : 1,"state" : 1,"stateStr" : "PRIMARY","uptime" : 324,"optime" : {"ts" : Timestamp(1609847597, 1),"t" : NumberLong(1)},"optimeDate" : ISODate("2021-01-05T11:53:17Z"),"syncSourceHost" : "","syncSourceId" : -1,"infoMessage" : "","electionTime" : Timestamp(1609847595, 1),"electionDate" : ISODate("2021-01-05T11:53:15Z"),"configVersion" : 1,"configTerm" : 1,"self" : true,"lastHeartbeatMessage" : ""},{"_id" : 2,"name" : "192.168.188.131:27019","health" : 1,"state" : 2,"stateStr" : "SECONDARY","uptime" : 18,"optime" : {"ts" : Timestamp(1609847597, 1),"t" : NumberLong(1)},"optimeDurable" : {"ts" : Timestamp(1609847597, 1),"t" : NumberLong(1)},"optimeDate" : ISODate("2021-01-05T11:53:17Z"),"optimeDurableDate" : ISODate("2021-01-05T11:53:17Z"),"lastHeartbeat" : ISODate("2021-01-05T11:53:21.839Z"),"lastHeartbeatRecv" : ISODate("2021-01-05T11:53:21.347Z"),"pingMs" : NumberLong(0),"lastHeartbeatMessage" : "","syncSourceHost" : "192.168.188.131:27018","syncSourceId" : 1,"infoMessage" : "","configVersion" : 1,"configTerm" : 1},{"_id" : 3,"name" : "192.168.188.131:27020","health" : 1,"state" : 2,"stateStr" : "SECONDARY","uptime" : 18,"optime" : {"ts" : Timestamp(1609847597, 1),"t" : NumberLong(1)},"optimeDurable" : {"ts" : Timestamp(1609847597, 1),"t" : NumberLong(1)},"optimeDate" : ISODate("2021-01-05T11:53:17Z"),"optimeDurableDate" : ISODate("2021-01-05T11:53:17Z"),"lastHeartbeat" : ISODate("2021-01-05T11:53:21.841Z"),"lastHeartbeatRecv" : ISODate("2021-01-05T11:53:21.343Z"),"pingMs" : NumberLong(0),"lastHeartbeatMessage" : "","syncSourceHost" : "192.168.188.131:27018","syncSourceId" : 1,"infoMessage" : "","configVersion" : 1,"configTerm" : 1}],"ok" : 1,"$clusterTime" : {"clusterTime" : Timestamp(1609847597, 1),"signature" : {"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),"keyId" : NumberLong(0)}},"operationTime" : Timestamp(1609847597, 1)
    }

    可以看到,最后我们设置的192.168.188.131:27018这一台被自动分配成了主机

至此集群搭建便完毕了,接下来就可以共享数据了,测试数据共享时一定要记得从机默认不进行读写,所以需要先使用rs.slaveOk()命令开启读写

Java云同桌学习系列(二十二)——mongoDB数据库相关推荐

  1. java云同桌学习系列(十四)——JavaScript语言

    本博客java云同桌学习系列,旨在记录本人学习java的过程,并与大家分享,对于想学习java的同学,可以随着我的步伐一起进步,我希望这个系列能够鼓励大家一同与我学习java,成为"云同桌& ...

  2. Java云同桌学习系列(十九)——Linux系统

    本博客java云同桌学习系列,旨在记录本人学习java的过程,并与大家分享,对于想学习java的同学,我希望这个系列能够鼓励大家一同与我学习java,成为"云同桌". 每月预计保持 ...

  3. Java云同桌学习系列(十五)——MySQL数据库

    本博客java云同桌学习系列,旨在记录本人学习java的过程,并与大家分享,对于想学习java的同学,我希望这个系列能够鼓励大家一同与我学习java,成为"云同桌". 每月预计保持 ...

  4. java云同桌学习系列(十)——网络编程

    本博客java云同桌学习系列,旨在记录本人学习java的过程,并与大家分享,对于想学习java的同学,我希望这个系列能够鼓励大家一同与我学习java,成为"云同桌". 每月预计保持 ...

  5. Java云同桌学习系列(十三)——前端技术之HTML与CSS

    本博客java云同桌学习系列,旨在记录本人学习java的过程,并与大家分享,对于想学习java的同学,可以跟随我的步伐一起学习,我希望这个系列能够鼓励大家一同与我学习java,成为"云同桌& ...

  6. java云同桌学习系列(七)——集合

    本博客java云同桌学习系列,旨在记录本人学习java的过程,并与大家分享,对于想学习java的同学,我希望这个系列能够鼓励大家一同与我学习java,成为"云同桌". 每月预计保持 ...

  7. 点云深度学习系列博客(二): 点云配准网络PCRNet

    目录 一. 简介 二. 基础结构 三. 项目代码 四. 实验结果 总结 Reference 今天的点云深度学习系列博客为大家介绍一个用于点云配准的深度网络:PCRNet [1].凡是对点云相关应用有些 ...

  8. WP8.1学习系列(第二十二章)——在页面之间导航

    在本文中 先决条件 创建导航应用 Frame 和 Page 类 页面模板中的导航支持 在页面之间传递信息 缓存页面 摘要 后续步骤 相关主题 重要的 API Page Frame Navigation ...

  9. WP8.1学习系列(第十二章)——全景控件Panorama开发指南

    2014/6/18 适用于:Windows Phone 8 和 Windows Phone Silverlight 8.1 | Windows Phone OS 7.1 全景体验是本机 Windows ...

  10. IT职场人生系列之十二:语言与技术I

    本文是IT职场人生系列的第十二篇. 最近移动互联网很流行,很多人都在学习IOS.Android编程.这也引起一个入行.改行的潮流. 那么,作为新手.老手,应该怎样选择自己学习的语言和技术呢? 本人从早 ...

最新文章

  1. XXL-CONF v1.4.1 发布,分布式配置管理平台
  2. java实现遍历树形菜单方法——service层
  3. (转)IOS学习笔记-2015-03-29 int、long、long long取值范围
  4. poi报空指针_POI 导出文件 报空指针异常 --Docker 中
  5. mysql 2027_阿里云mysql远程登录报ERROR 2027(HY000)
  6. SQLServer数据库,表内存,实例名分析SQL语句
  7. Bootstrap3 栅格系统之列嵌套
  8. signature=12e3283d637b587235bcb4cbbfa1a5b3,A pathogen-inducible endogenous siRNA in plant immunity
  9. python画曲线图-python怎么画曲线图
  10. 嵌入式开发与C++开发的区别是什么?
  11. Linux(Fedora 20) EFI 启动Windows出错 \EFI\Microsoft\Boot\bootmgfw.efi is missing
  12. 六星经典CSAPP-笔记(7)加载与链接(上)
  13. qq空间登录参数详细分析及密码加密最新版
  14. ASEMI的MOS管9N90参数,9N90电路图,9N90实物图
  15. IPSec IKEV2
  16. SIFT(尺度不变特征变换)的原理分析
  17. C++ : 陶陶摘苹果
  18. 年薪百万的阿里 P7 到底该具备什么样的能力?!解密篇
  19. PTA自测-1 打印沙漏 python实现
  20. mixly编程怎样音乐_使用mixly和Arduino结合蜂鸣器播放音乐

热门文章

  1. Start request repeated too quickly解决方法
  2. ShopNc安装过程
  3. 面试时候HR问你的职业规划?
  4. linux cat 压缩文件,Linux cat和zcat命令可能比你意识到的更有用
  5. ZoomIt v4.5
  6. Web项目【用户管理系统】完整版
  7. Opencv多版本共存问题
  8. cf. (E) Thematic Contests
  9. 阿里云数据库(RDS)是什么,与传统数据库有什么区别?
  10. 服务器网页内容修改了不变动,修改服务器网页