MongoDB介绍
MongoDB是一个开源文档数据库,提供高性能、高可用性和自动伸缩能力。
适用场景:电商中商品的评论以及购物车等、内容管理(今日头条的新闻、在线教育的课程等)、游戏场景(使用 MongoDB 存储游戏用户信息,用户的装备、积分等直接以内嵌文档的形式存储,方便查询、更新)等对事物没有特别高要求的单表操作。尤其是在数据量达到千万级别以上的时候,MongoDB基于副本机制的高可用以及其提供的水平可扩展能力相对于mysql这种关系型数据库具有特别大的优势(基于mysql分库分表是非常麻烦的事情)。
不适合的场景:像转账这种对事务要求特别高的场景。
MongoDB并不像关系型数据库支持关联查询,所以使用MongoDB必须通过程序去维护这种关系。(在项目中,使用mysql这样的关系型数据库,也建议用程序去维护这种关系。相对于sql,程序可读性更高,其次大量的关联查询会影响性能)
在MongoDB 中的1条记录称为1个文档(类似于mysql表中的1条记录),1个文档由多个filed:value这种键值对组成,类似于json这种数据格式。
多个文档组成1个集合(相当于mysql中的1张表)
多个集合组成1个数据库,每个数据库都是独立的,有自己的用户、权限信息等。
安装
下载:wget http://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.4.18.tgz
解压
[root@suzhe opt]# tar -zxvf mongodb-linux-x86_64-3.4.18.tgz[root@suzhe opt]# mv mongodb-linux-x86_64-3.4.18 mongodb
创建目录
[root@suzhe opt]# cd mongodb/[root@suzhe mongodb]# mkdir data[root@suzhe mongodb]# mkdir logs
bin目录创建mongodb的配置文件:
[root@suzhe mongodb]# vim bin/mongodb.conf
storage: dbPath: /opt/mongodb/data #数据存储目录systemLog: destination: file path: /opt/mongodb/logs/mongodb.log #日志存储目录 logAppend: truenet: port: 27017 #端口 bindIp: 0.0.0.0 #默认绑定所有ipprocessManagement: fork: true #后台启动security: authorization: disabled #默认disabled关闭授权验证, enabled启用授权
进入bin目录启动mongo
[root@suzhe bin]# ./mongod --config mongodb.conf
查看进程
[root@suzhe bin]# ps -ef|grep mongoroot 27346 1 1 09:46 ? 00:00:00 ./mongod --config mongodb.confroot 27480 25329 0 09:47 pts/0 00:00:00 grep --color=auto mongo[root@suzhe bin]#
mongodb shell操作
启动shell
执行bin目录下的mongo,进入shell。
使用db展示数据库,应该会返回test,它是默认的数据库。
> dbtest>
切换数据库使用 use <database>
> use helloswitched to db hello>
这时候数据库hello并不会创建,只有第一次向数据库中插入记录或者创建集合的时候,它才会被创建。
1、插入操作
insertOne方法:插入一条记录
db.inventory.insertOne( { item: "canvas", qty: 100, tags: ["cotton"], size: { h: 28, w: 35.5, uom: "cm" } })
查询所有的记录:db.inventory.find({})
> db.inventory.find({}){ "_id" : ObjectId("5ccd3e299553b44433f36e46"), "item" : "canvas", "qty" : 100, "tags" : [ "cotton" ], "size" : { "h" : 28, "w" : 35.5, "uom" : "cm" } }>
可以看到记录已经插入成功,从返回的结果发现记录中多了一个"_id"字段,每一个记录都必须有唯一的_id,我们自己可以指定,如果不指定,mongo会自己生成一个。如果指定的_id在集合中已经存在相同_id的记录,会插入失败。
如果集合当前不存在,插入操作将创建集合。
插入多条记录:insertMany方法
db.inventory.insertMany([ { item: "journal", qty: 25, tags: ["blank", "red"], size: { h: 14, w: 21, uom: "cm" } }, { item: "mat", qty: 85, tags: ["gray"], size: { h: 27.9, w: 35.5, uom: "cm" } }, { item: "mousepad", qty: 25, tags: ["gel", "blue"], size: { h: 19, w: 22.85, uom: "cm" } }])
查询所有的记录,可以看到多条插入成功
> db.inventory.find({}){ "_id" : ObjectId("5ccd3e299553b44433f36e46"), "item" : "canvas", "qty" : 100, "tags" : [ "cotton" ], "size" : { "h" : 28, "w" : 35.5, "uom" : "cm" } }{ "_id" : ObjectId("5ccd3eb39553b44433f36e47"), "item" : "journal", "qty" : 25, "tags" : [ "blank", "red" ], "size" : { "h" : 14, "w" : 21, "uom" : "cm" } }{ "_id" : ObjectId("5ccd3eb39553b44433f36e48"), "item" : "mat", "qty" : 85, "tags" : [ "gray" ], "size" : { "h" : 27.9, "w" : 35.5, "uom" : "cm" } }{ "_id" : ObjectId("5ccd3eb39553b44433f36e49"), "item" : "mousepad", "qty" : 25, "tags" : [ "gel", "blue" ], "size" : { "h" : 19, "w" : 22.85, "uom" : "cm" } }>
2、查询操作
删除集合:
> db.inventory.drop()true>
插入多条记录:
db.inventory.insertMany([ { item: "journal", qty: 25, size: { h: 14, w: 21, uom: "cm" }, status: "A" }, { item: "notebook", qty: 50, size: { h: 8.5, w: 11, uom: "in" }, status: "A" }, { item: "paper", qty: 100, size: { h: 8.5, w: 11, uom: "in" }, status: "D" }, { item: "planner", qty: 75, size: { h: 22.85, w: 30, uom: "cm" }, status: "D" }, { item: "postcard", qty: 45, size: { h: 10, w: 15.25, uom: "cm" }, status: "A" }]);
查询所有的记录:
db.inventory.find({})
相当于
SELECT * FROM inventory
定义相等的条件过滤可以使用如下的格式
{: , ... }
查询状态等于“D”的元素
> db.inventory.find({status:"D"}){ "_id" : ObjectId("5ccd40889553b44433f36e4c"), "item" : "paper", "qty" : 100, "size" : { "h" : 8.5, "w" : 11, "uom" : "in" }, "status" : "D" }{ "_id" : ObjectId("5ccd40889553b44433f36e4d"), "item" : "planner", "qty" : 75, "size" : { "h" : 22.85, "w" : 30, "uom" : "cm" }, "status" : "D" }>
相当于
SELECT * FROM inventory WHERE status = "D"
查询运算符$in:查询状态等于“A”或者等于“D”的记录
db.inventory.find( { status: { $in: [ "A", "D" ] } } )
相当于
SELECT * FROM inventory WHERE status in ("A", "D")
查询状态等于“A”和qty<30的记录
db.inventory.find( { status: "A", qty: { $lt: 30 } } )
相当于
SELECT * FROM inventory WHERE status = "A" AND qty < 30
查询状态等于“A”或者qty<30的记录
db.inventory.find( { $or: [ { status: "A" }, { qty: { $lt: 30 } } ] } )
相当于sql
SELECT * FROM inventory WHERE status = "A" OR qty < 30
查询status=“A” 这一条件 和 qty<30或者item已p开头(这里是正则表达式)的这一条件 同时成立的记录。
db.inventory.find( { status: "A", $or: [ { qty: { $lt: 30 } }, { item: /^p/ } ]} )
相当于
SELECT * FROM inventory WHERE status = "A" AND ( qty < 30 OR item LIKE "p%")
数组精确匹配:tags 包含两个元素 并且red和bank顺序也要一样
db.inventory.find( { tags: ["red", "blank"] } )
数组多元素查询:查询数组中包含red和blank的记录
db.inventory.find( { tags: { $all: ["red", "blank"] } } )
数组单元素查询:查询tags中包含plain的记录
db.inventory.find( { tags: "plain" } )
查询数组dim_cm至少有1个值大于25的元素
> db.inventory.find( { dim_cm: { $gt: 25 } } ){ "_id" : ObjectId("5ccd47839553b44433f36e52"), "item" : "planner", "qty" : 75, "tags" : [ "blank", "red" ], "dim_cm" : [ 22.85, 30 ] }>
3、修改操作
准备数据
db.inventory.insertMany( [ { item: "canvas", qty: 100, size: { h: 28, w: 35.5, uom: "cm" }, status: "A" }, { item: "journal", qty: 25, size: { h: 14, w: 21, uom: "cm" }, status: "A" }, { item: "mat", qty: 85, size: { h: 27.9, w: 35.5, uom: "cm" }, status: "A" }, { item: "mousepad", qty: 25, size: { h: 19, w: 22.85, uom: "cm" }, status: "P" }, { item: "notebook", qty: 50, size: { h: 8.5, w: 11, uom: "in" }, status: "P" }, { item: "paper", qty: 100, size: { h: 8.5, w: 11, uom: "in" }, status: "D" }, { item: "planner", qty: 75, size: { h: 22.85, w: 30, uom: "cm" }, status: "D" }, { item: "postcard", qty: 45, size: { h: 10, w: 15.25, uom: "cm" }, status: "A" }, { item: "sketchbook", qty: 80, size: { h: 14, w: 21, uom: "cm" }, status: "A" }, { item: "sketch pad", qty: 95, size: { h: 22.85, w: 30.5, uom: "cm" }, status: "A" }]);
在inventory集合上使用db.collection.updateOne()方法更新item等于“paper”的第一条记录。
db.inventory.updateOne( { item: "paper" }, { $set: { "size.uom": "cm", status: "P" }, $currentDate: { lastModified: true } })
第一个{}参数是过滤条件,第二个参数是要更新的值。
使用$set操作符更新uom字段为“cm”,状态字段值为“P”
使用$currentDate操作符将lastModified字段的值更新为当前日期。如果lastModified字段不存在,$currentDate将创建该字段。
使用db.collection.updateMany()方法更新所有qty小于50的文档
db.inventory.updateMany( { "qty": { $lt: 50 } }, { $set: { "size.uom": "in", status: "P" }, $currentDate: { lastModified: true } })
替换item等于paper的第一条记录为新设置的文档
db.inventory.replaceOne( { item: "paper" }, { item: "paper", instock: [ { warehouse: "A", qty: 60 }, { warehouse: "B", qty: 40 } ] })
4、删除操作
删除status等于“A”的记录:{}里的内容则为过滤条件
db.inventory.deleteMany({ status : "A" })
deleteOne方法则会删除符合条件的第1条记录
db.inventory.deleteOne( { status: "D" } )
5、分页查询
skip(n):跳过n条数据 limit(n):限制n条数据
> db.inventory.find({}).skip(3).limit(2)
6、排序
sort():db.inventory.find().sort({"item":1}).pretty()
1:升序 -1:降序
pretty() 方法可以格式化数据,使数据易于阅读。
7、聚合分组
nosqlbooster工具
下载安装
https://nosqlbooster.com/downloads
连接
3、选中数据库
3、点击
可以看到弹出了生成查询语句的框
更多详细的shell操作,可查看官方文档: