Skip to main content

分布式数据库-MongoDB

分布式数据库-MongoDB

简介

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

安装

sw_64暂不支持

sudo yum install mongodb mongodb-server -y

14 MB/s|32kB 00:00 (2/3):mongodb-4.0.1-6.ue120.aarch64.rpm 49MB/s| 11 MB 00:00 68MB/s| 21 MB 00:00 (3/3):mongodb-server-4.0.1-6.ue120.aarch64.pm 总计 102MB/s|33 MB 00:00 运行事务检查 事务检查成功。 运行事务测试 事务测试成功。)

启动

systemctl start mongod.service

systemctl status mongod.service

Active:active (running)since Fri 2021-01-22 13:12:32CST;58min ago Docs:https://docs.mongodb.org/manual Process:3944 ExectartPre=/us/bin/mkdir-p /var/run/mongodb (code=exited, status=0/SUCCESS) Process:3946 ExecstartPre/us/bin/chown mongod:mongod /vax/run/mongodb (codeexited,status= Process:39 xtartre=/us/bi/chmod 0755 /var/run/mongod (ode=exitd,status=0/SUCCESS) rocess:3950 Exetart=/us/bin/mongod PIONS (code=exited,sttus=0/SUCCESS) Main PID:3952 (mongod) Memory:170.6M CGroup:/system.slice/mongod.service L3952 /us/bin/mongod-f /etc/mongod.conf 1月 22 13:12:31 1ocalhost.1ocaldomain systemd [1]:Starting MongoDB Database Server... 1月22 13:12:31 localhost.1ocaldomain mongod[3950]:about to fork child process, waiting unti ser 1月22 13:12:31 localhost.localdomain mongod[3950]:forked process:3952 1月22 13:12:32 localhost.localdomain mongod[3950]:child process started successfully,parentexi 1月 22 13:12:32 localhost.1ocaldomain systemd[1]:Started MongoDB Database Server. lines 1-18/18(END))

默认情况下,启动MongoDB后会初始化以下两个目录:

  • 数据存储目录:/var/lib/mongodb。

  • 日志文件目录:/var/log/mongodb。

配置实例

配置文件位于“/etc/mongod.conf”,使用 = 的格式,默认配置即可使用大部分功能。

vi /etc/mongod.conf

连接实例

通过mongo命令来连接mongoDB的命令:

mongo [options] [db address] [file names]

之前启动实例是在本地27017端口,安全模式未被开启,所以不需要输入用户名和密码即可直接连接:

mongo 127.0.0.1:27017

或者通过--host和--port选项指定主机和端口。一切顺利的话,就进入了mongoDB shell。shell会报出一连串权限警告,不过不用担心,这并不会影响之后的操作,在添加授权用户和开启认证后,这些警告会自动消失。

The monitoring data will be available on a ongoDB website with a unique URL accessible to you and anyone you share the URL with. MongoDB may use this information to make product improvements and to suggest MongoDB products and deployment options to you. o enale free montoring,un the following comand:d.enaleFreeMonitoring() o pemanently disablethis eminde,unth following command:db.disableFreeMonitoring())

数据库基本操作

在进行增查改删操作之前,先了解下常用的shell操作:

  • db:显示当前所在数据库,默认为test。

  • show dbs:列出可用数据库。

  • show tables/show collections:列出数据库中可用集合。

  • use :用于切换数据库。

mongoDB预设有两个数据库,即admin和local。admin用来存放系统数据,local用来存放该实例数据。在副本集中,一个实例的local数据库对于其它实例是不可见的。

使用use命令可切换数据库:

use admin> use local> use newDatabase

可以用use命令切换至一个不存在的数据库,当您存入新数据时,mongoDB会创建这个数据库:

use newDatabase

db.newCollection.insert({x:1})

WriteResult({ "nInserted" : 1 })

WriteResult({"nInserted":1}))

以上命令向数据库中插入一个文档,返回1表示插入成功,mongoDB自动创建newCollection集合和数据库newDatabase。下面将创建一个drivers集合,进行增查改删操作。

  • 创建(Create):MongoDB提供insert方法创建新文档。

◆db.collection.inserOne()插入单个文档

◆WriteResult({ "nInserted" : 1 })

◆db.collection.inserMany()插入多个文档

◆db.collection.insert()插入单条或多条文档

这里以insert方法为例:

db.drivers.insert({name:"Chen1fa",age:18})

db.drivers.insert({name:"Xiaose",age:35})

db.drivers.insert({_id:91,name:"Sun1feng",age:34})

要注意,age:18和age:"18"是不一样的,前者插入的是数值,后者插入的是字符串。插入新文档如果未指定_id,mongoDB会自动为插入的文档添加_id字段。使用db.drivers.find()命令即可看到刚刚插入的文档:

db.drivers.find()

{ "_id" : ObjectId("598964bd56b8c69ae1e5f36a"), "name" : "Chen1fa", "age" : 18 }

{ "_id" : ObjectId("598964d456b8c69ae1e5f36b"), "name" : "Xiaose", "age" : 35 }

{ "_id" : 91, "name" : "Sun1feng", "age" : 34 }

WriteResult("nInserted":1}) d.drivers.insert((name:"Xiaose"g:35}) WriteResult("nInserted":1}) d.drivers.insert({_id:91,name:"Sun1feng",age:34)) WriteResult({"nInserted":1}) db.drivers.find() "d":bjectd("600a70461dc252684cce01"),"name:"Chenfa","age:18} "djt("600704ddc255268acce02"),"nam:"iose,"g:35} "_id:91,"name":"Sun1feng","age:34})

  • 查找(Read):MongoDB提供find方法查找文档,第一个参数为查询条件。

// 查找所有文档

db.drivers.find()

{ "_id" : ObjectId("598964bd56b8c69ae1e5f36a"), "name" : "Chen1fa", "age" : 18 }

{ "_id" : ObjectId("598964d456b8c69ae1e5f36b"), "name" : "Xiaose", "age" : 35 }

{ "_id" : 91, "name" : "Sun1feng", "age" : 34 }

// 查找 name 为 Xiaose 的文档

db.drivers.find({name: "Xiaose"})

{ "_id" : ObjectId("598964d456b8c69ae1e5f36b"), "name" : "Xiaose", "age" : 35 }

// 查找 age 大于 20 的文档

db.drivers.find({age:{$gt:20}})

{ "_id" : ObjectId("598964d456b8c69ae1e5f36b"), "name" : "Xiaose", "age" : 35 }

{ "_id" : 91, "name" : "Sun1feng", "age" : 34 }

{"d:d("600a70461dc2552684cce01"),"name:"henfa","age:18} {"d:bjectd("600a70d1dc2552684acce02"),"nam:"Xiaose","g:35} {"id":91,"name":"Sunfeng","age:34}

db.drivers.find(name:"Xiaose"}) {"d:bjectd("600a704d1dc2552684acce02"),"name:"iaose","age:35} db.drivers.find( {age:($Sgt:20}}) {"dject("600a74d1dc2552684acce02"),"name":"iase","age:35} {"id":91,"name:"un1feng","age":34})

上述代码中的$gt对应于大于号>的转义。第二个参数可以传入投影(projection,投影仪中,白色光源通过分光镜、液晶板、投影镜头的光学变换后,投射到反射面上,显示出了彩色图像)文档映射数据:

db.drivers.find({age:{$gt:20}},{name:1})

{ "_id" : ObjectId("598964d456b8c69ae1e5f36b"), "name" : "Xiaose" }

{ "_id" : 91, "name" : "Sun1feng" }

dbjectd("600704d1dc2552684acce02"),"name":"Xiaose} ("d":91,"na"sunfeng))

上述命令将查找age大于20的文档,返回name字段,排除其它字段。投影文档中字段为1或真值表示包含,0或假值表示排除,可以设置多个字段为1或0,但不能混合使用。除此之外,还可以通过count、skip、limit等指针(Cursor)方法,改变文档查询的执行方式:

db.drivers.find().count() #统计查询文档数目3

db.drivers.find().skip(1).limit(10).sort({age:1})

{ "_id" : 91, "name" : "Sun1feng", "age" : 34 }

{ "_id" : ObjectId("598964d456b8c69ae1e5f36b"), "name" : "Xiaose", "age" : 35 }

3

db.drivers.find(),skip(1).1imit(10).ort({age:1}) {"id":91,"name":"Sun1feng","age":34} {"d":bjectd("600a704d1dc2552684acce02"),"nae:"Xiaoseg:35})

上述查找命令跳过1个文档,限制输出10个,以name子段正序排序(大于0为正序,小于0位反序)输出结果。可以使用Cursor方法中的pretty方法,提升查询文档的易读性,特别是在查看嵌套的文档和配置文件的时候:

db.drivers.find().pretty()

f "detd"600761c255264ce0), "nam:Chen1fa, "age:18 }f "d:jetd"600704d1dc255264acce02), "nae"iaose, "age":35 } {"id":91,nae:"unfeng""age:34))

  • 排序(Sort):在MongoDB中使用sort()方法对数据进行排序。sort()方法可以通过参数指定排序的字段,并使用1和-1来指定排序的方式,其中1为升序排列,而-1是用于降序排列。

◆语法:sort()方法基本语法如下所示。

db.COLLECTION_NAME.find().sort({KEY:1})

◆实例:以下实例演示了drivers集合中的数据按字段age的降序排列。

db.drivers.find({},{"name":1,"age":1,_id:0}).sort({"age":-1})

{ "name" : "Xiaose", "age" : 35 }

{ "name" : "Sun1feng", "age" : 34 }

{ "name" : "Chen1fa", "age" : 18 }

"nae":"Xiaose","age:35} "name:"Sunfeng","age:3} {"name":"Chen1fa","age:18})

  • 更新(Update):MongoDB提供updata方法更新文档。

◆db.collection.updateOne():更新最多一个符合条件的文档。

◆db.collection.updateMany():更新所有符合条件的文档。

◆db.collection.replaceOne():替代最多一个符合条件的文档。

◆db.collection.update():默认更新一个文档,可配置multi参数后更新多个文档。

以update()方法为例,其格式如下:

db.collection.update(

,

,

{

    upsert: <boolean>,

    multi: <boolean>

}

)

各参数意义:

◆query为查询条件。

◆update为修改的文档。

◆upsert为真,查询为空时插入文档。

◆multi为真,更新所有符合条件的文档。

下面的命令将name字段为Chen1fa的文档,更新age字段为30,并添加身高字段:

db.drivers.update({name:"Chen1fa"},{name:"Chen1fa", age:30, height:173})

db.drivers.update({name:"Sun1feng"},{name:"Sun1feng", age:34, height:171})

db.drivers.update({name:"Xiaose"},{name:"Xiaose", age:35, height:176})

WriteResult({"nMatched":1,"nUpserte:,"nModified":1}) d.drivers.update {name:"Sun1feng"),(name:"Sun1feng",age:34,height:171})

WriteResult("nMatched":1,"nUpserted":0,"odifie:1}) d.drivers.update(name:"Xiaose"},(name:"Xiaose",age:35,eight:176}) WriteResult(f"nMatched":1,"nUpserted:0,"nModified:1}))

要注意的是,如果更新文档只传入age字段,那么文档会被更新为{age: 30},而不是{name:"Chen1fa", age:30}。要避免文档被覆盖,需要用到set指令,set仅替换或添加指定字段:

db.drivers.update({name:"Chen1fa"},{$set:{age:30}})

WriteResult("nMatched":1,nUperte:,"noified0}))

如果要在查询的文档不存在的时候插入文档,要把upsert参数设置真值:

db.drivers.update({name:"Alen"},{age:24},{upsert: true})

WriteResult({ "natched":0, "nUpserted:1, "nodified0 "jectd(600720aacff2c3755a))

update方法默认情况只更新一个文档,如果要更新符合条件的所有文档,要把multi设为真值,并使用$set指令:

db.drivers.update({age:{$gt:25}},{$set:{license:'A'}},{multi: true})

db.drivers.update({age:{$lt:25}},{$set:{license:'C'}},{multi: true})

WriteResult({"nMatched":3,"nUpserted":0,ndified:3})

db.drivers.update(fage:($lt:25)},(Sset:(license:"C"}),(multi:true)) WriteResult("nMatched":1,"nUserted:0,"noified:1}))

最终结果:

db.drivers.find()

{ "_id" : ObjectId("598964bd56b8c69ae1e5f36a"), "name" : "Chen1fa", "age" : 30, "height" : 173, "license" : "A" }

{ "_id" : ObjectId("598964d456b8c69ae1e5f36b"), "name" : "Xiaose", "age" : 35, "height" : 176, "license" : "A" }

{ "_id" : 91, "name" : "Sun1feng", "age" : 34, "license" : "A" }

{ "_id" : ObjectId("598968b3ed1eccef17e79abe"), "age" : 24, "license" : "C" }

  • 索引(Index):索引通常能够极大的提高查询的效率,如果没有索引,MongoDB在读取数据时必须扫描集合中的每个文件并选取那些符合查询条件的记录。这种扫描全集合的查询效率是非常低的,特别在处理大量的数据时,查询可以要花费几十秒甚至几分钟,这对网站的性能是非常致命的。索引是特殊的数据结构,索引存储在一个易于遍历读取的数据集合中,索引是对数据库表中一列或多列的值进行排序的一种结构。

◆createIndex()方法:MongoDB使用createIndex()方法来创建索引。

语法:createIndex()方法基本语法格式如下所示。

db.collection.createIndex(keys, options)

语法中Key值为您要创建的索引字段,1为指定按升序创建索引,如果您想按降序来创建索引指定为-1即可。

实例:

db.drivers.createIndex({"age":1})

「1 "reatedollectionAutomatically":false, "numIndexesBefore":1, "numIndexesAfter":2, "ok":1)

createIndex()方法中您也可以设置使用多个字段创建索引(关系型数据库中称作复合索引)。

db.drivers.createIndex({"age":1,"height":-1})

L "reollectionutomatically:false, "numIndexesBefore":2, "numIndexesfter":3, "ok":1)

在后台创建索引:

db.drivers.createIndex({"age":1,"height":-1}, {background: true})

通过在创建索引时加background:true的选项,让创建工作在后台执行。

◆其他操作

查看集合索引:

db.drivers.getIndexes()

"V":2, "key"{ "id":1 }, "nae":"d "nnewtbae.drivers "V":2, "key":{ "age:1 }, "nae":"ge_1", "nnee.driver "v":2, "key":{ "age":1, "height" :-1 }, "nae :"age_1_height_-1", "n":"natabase.drivers")

查看集合索引大小:

db.drivers.totalIndexSize()

删除集合指定索引:

db.drivers.dropIndex("索引名称")

{"nIndexeswas":3,"ok":1})

删除集合所有索引:

db.drivers.dropIndexes()

{ "nIndexesa"2 "mgndexes doppedfor collection, "ok":1)

  • 删除(Delete):MongoDB提供了delete方法删除文档。

◆db.collection.deleteOne():删除最多一个符合条件的文档。

◆db.collection.deleteMany():删除所有符合条件的文档。

◆db.collection.remove() 删除一个或多个文档。

以remove方法为例:

db.drivers.remove({name:"Xiaose"}) #删除所有name为Xiaose的文档

db.drivers.remove({age:{$gt:30}},{justOne:true}) #删除所有age大于30的文档

db.drivers.find()

{ "_id" : ObjectId("598964bd56b8c69ae1e5f36a"), "name" : "Chen1fa", "age" : 30, "license" : "A" }

{ "_id" : ObjectId("598968b3ed1eccef17e79abe"), "age" : 24, "license" : "C" }

MongoDB提供了drop方法删除集合,返回true表面删除集合成功:

db.drivers.drop()

  • 关闭实例:关闭mongoDB服务。

use admin

db.shutdownServer()

server should be down... 2021-01-22T14:39:23.885+0800I NETWORK [js] trying reconnect to 127.0.0.1:27017 failed 2021-01-22T14:39:23.886+0800I NETWORK [js] reconnect 127.0.0.1:27017 failed failed)

  • 使用exit或Ctrl + C断开连接。

exit

  • 其他操作:其他功能使用请参考mongodb官网指导。

◆https://docs.mongoing.com/

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