Java核心技术面试精讲 : www.sanzhishu.top/878.html
1、Mongodb概述
1.1、为何使用Mongodb?
Mongodb用来应对"三高"问题:
高并发:对数据库高并发读写的需求。 高性能:对海量数据的高效存储和访问的需求。 高可用:对数据库的高扩展性和高可用性的需求。
MySQL数据库在面临这"三高"时,显得力不从心,所以学习Mongodb才更能丰富业务场景的处理能力。
MongoDB 是一个开源的 NoSQL 数据库,具有高可扩展性、灵活性和可靠性等优点,适合于处理分布式、大规模和敏捷的数据存储需求。
1.2、业务应用场景
- 大型 Web 应用: MongoDB 可以存储非结构化、半结构化和结构化数据,适用于存储用户数据、日志、社交媒体内容等各种类型的数据。同时,MongoDB 支持水平扩展和负载均衡,可以满足大量请求的高并发访问需求。
- 实时数据分析: MongoDB 支持 MapReduce 和聚合管道等复杂的数据分析操作,可以处理海量实时数据,并将结果存储在集合中,方便后续查询和分析。此外,MongoDB 还支持全文搜索和地理空间索引等功能,可以对文本和地理位置数据进行快速检索。
- 物联网应用: MongoDB 支持 JSON 格式的数据存储和查询,适用于存储传感器数据、设备状态等物联网数据。MongoDB 还具有轻量级和低延迟的特点,可以提供实时响应和快速插入大量数据的能力。
- 游戏应用: MongoDB 支持文档型数据存储和 ACID 事务,适用于存储游戏数据、用户配置等各种类型的数据。MongoDB 还支持多语言驱动程序和分片集群等特性,可以满足高并发的游戏场景需求。
- 移动应用: MongoDB 支持可嵌入的文档型数据库模式和 BSON 格式,适用于移动设备端本地存储和离线访问。同时,MongoDB 还支持数据同步和副本集备份等功能,可以确保数据在不同设备之间的一致性。
1.3、Mongodb和MySQL的区别
MySQL Mongodb
数据库(database)数据库(database)表(table)collection(集合)行(row)document(文档)字段(column)field(字段)索引(index)index(索引)primary key(主键)primary key(主键 _id)
2、Mongodb安装
2.1、Windows系统中安装启动
第一步,下载安装包
MongoDB 提供了可用于 32 位和 64 位系统的预编译二进制包,可以从 MongoDB 官网下载安装, MongoDB 预编译二进制包下载地址: www.mongodb.com/download-ce…
选择下载版本以及下载环境,msi安装包,点击Download按钮下载
dbpath=E:\java\Mongodb\data\db logpath=E:\java\Mongodb\log\mongod.log#日志输出文件路径 logappend=true#错误日志采用追加模式 journal=true#启用日志文件,默认启用 quiet=true #过滤掉无用的日志信息,若需要调试使用请设置为false port=27017 #端口号 默认为27017
启动,cmd窗口输入以下命令
mongod --dbpath "安装路径\db" --logpath "安装路径\mongod.log" --install -serviceName "MongoDB"
访问localhost:27017,如果出现以下页面,代表安装成功
可以通过services.msc打开服务列表,找到mongodb的服务查看
配置环境变量,在Path环境中添加一个mongodb的环境
输入mongo,如果出现以下信息,代表配置成功
3、Mongodb的操作
3.1、数据库操作
选择和创建数据库的语法格式:
连接mongodb数据库
mongo
显示所有数据库
show databases;
选择使用数据库
use 数据库名
删除数据库
db.dropDatabase()
3.2、集合操作
集合,也类似与关系型数据库中的表
显示出所有集合
show tables
或者
show collections
3.2.1、集合显式创建
db.createCollection(name)
其中name为集合的名字
集合的命名规范 1、集合名不能是空字符串 "" 。 2、集合名不能含有 \0 字符(空字符 ) ,这个字符表示集合名的结尾。 3、集合名不能以 "system." 开头,这是为系统集合保留的前缀。 4、用户创建的集合名字不能含有保留字符。有些驱动程序的确支持在集合名里面包含,这是因为某些系统生成的集合中包含该字符。除非你要访问这种系统创建的集合,否则千万不要在名字里出现$ 。
3.2.2、集合的隐式创建
当向一个集合中插入一个文档的时候,如果集合不存在,则会自动创建集合。
提示:通常使用隐式创建文档即可。
3.2.3集合的删除
db.collection.drop()
或者
db.集合名.drop()
返回值
如果成功删除选定集合,则 drop() 方法返回 true ,否则返回 false 。
例如:要删除 mycollection 集合
db.mycollection.drop()
3.3、文档基本CRUD
文档( document )的数据结构和 JSON 基本一样。 所有存储在集合中的数据都是 BSON 格式。
3.3.1、文档插入
(1)单个文档插入
使用insert()或save()方法向集合中插入文档
提示: 1、 集合如果不存在,则会隐式创建。 2、mongo 中的数字,默认情况下是 double 类型,如果要存整型,必须使用函数 NumberInt( 整型数字 ) ,否则取出来就有问题了。 3、插入当前日期使用 new Date()。 4、插入的数据没有指定 _id ,会自动生成主键值。 5、如果某字段没值,可以赋值为 null ,或不写该字段。 6、出现WriteResult({"nInserted":1})就代表添加成功。
注意:
- 文档中的键 / 值对是有序的。
- 文档中的值不仅可以是在双引号里面的字符串,还可以是其他几种数据类型(甚至可以是整个嵌入的文档 ) 。
- MongoDB 区分类型和大小写。
- MongoDB 的文档不能有重复的键。
- 文档的键是字符串。除了少数例外情况,键可以使用任意 UTF-8 字符。 文档键命名规范: 键不能含有 \0 ( 空字符 ) 。这个字符用来表示键的结尾。 . 和 $ 有特别的意义,只有在特定环境下才能使用。 以下划线 "_" 开头的键是保留的 ( 不是严格要求的 ) 。
批量插入
db.集合名.insertMany([{document1},{document2},{document3}...])
注意:插入时指定了 _id ,则主键就是该值,如果没有指定,则自动生成。
如果某条数据插入失败,将会终止插入,但已经插入成功的数据不会回滚掉。
因为批量插入由于数据较多容易出现失败,因此,可以使用 try catch 进行异常捕捉处理,测试的时候可以不处理。
try {
db.comment.insertMany([
{"name":"王五","age":23,"address":"天津"},{"name":"赵四","age":25,"address":"河北省"}
]);
} catch (e) {
print (e);
}
3.3.2、文档的基本查询
查询数据的语法格式如下:
db.集合名.find(<query>,[projection])</query>
Parameter Type Descriptionquery document
可选。使用查询运算符指定选择筛选器。若要返回集合中的所有文档,请省略此参数或传递空文档
( {} ) 。 projection document
可选。指定要在与查询筛选器匹配的文档中返回的字段(投影)。若要返回匹配文档中的所有字段,
请省略此参数
(1)查询所有
db.集合名.find()
db.集合名.find({})
(2)指定查询
会发现每条文档会有一个叫 _id 的字段,这个相当于我们原来关系数据库中表的主键,当你在插入文档记录时没有指定该字段, MongoDB会自动创建,其类型是 ObjectID 类型。
如果我们在插入文档记录时指定该字段也可以,其类型可以是 ObjectID 类型,也可以是 MongoDB 支持的任意类型。
比如我想查询 名字 为 张三 的记录,怎么办,很简单!只要在 fifind() 中添加参数即可,参数也是 json 格式,如下:
db.集合名.find({"name":"张三"})
如果你只需要返回符合条件的第一条数据,我们可以使用 fifindOne 命令来实现,语法和 fifind 一样。
如:查询用户编号是 name为王五 的记录,但只最多返回符合条件的第一条记录。
(3)投影查询(projection Query)
如果要查询结果返回部分字段,则需要使用投影查询(不显示所有字段,只显示指定的字段)。
如:查询结果只显示 _id 、 name 、age :
db.集合名.find({条件},{name:1,age:1})
默认_id 会显示。
如果不想显示主键_id,如下
db.集合名.find({条件},{name:1,age:1,_id:0})
查询所有数据,只显示_id和name、age
db.集合名.find({},{name:1,age:1})
3.3.3、文档的更新
db.collection.update(query, update, options)
Parameter
Type
Description
query
document
更新的选择条件。可以使用与 fifind ()方法中相同的查询选择器,类似 sql update 查询内 where 后面的。。在 3.0 版中进行了更改:当使用 upsert:true 执行 update ()时,如果查询使用点表示法在 _id 字段上指定条件,则 MongoDB 将拒绝插入新文档。
update
document
or
pipeline
要应用的修改。包含更新运算符表达式的文档,或仅包含:对的替换文档,或在 MongoDB 4.2 中启动聚合管道。
upsert
boolean
可选。如果设置为 true ,则在没有与查询条件匹配的文档时创建新文档。默认值为 false ,如果找不到匹配项,则不会插入新文档。
multi
boolean
可选。如果设置为 true ,则更新符合查询条件的多个文档。如果设置为 false ,则更新一个文档。默认值为 false 。
(1)覆盖的修改
如果我们想修改name为张三,地址改为河南, 输入以下语句
db.mymongodb.update({"name":"张三"},{address:'河南'})
修改之后,发现除了address字段,其他属性全部没有了,这是因为修改覆盖了原有的数据,没有填写值默认为空了。
(2)局部修改
为了解决上面的问题,我们需要使用修改器 $set 来实现,命令如下:
db.mymongodb.update({"name":"王五"},{$set:{name:'张三',age:23,address:'河南'}})
(3)批量修改
更新所有名叫张三的,修改地址为北京
//默认只修改第一条数据
db.mymongodb.update({name:"张三"},{$set:{address:"北京"}})
//修改所有符合条件的数据
db.mymongodb.update({name:"张三"},{$set:{address:"北京"}},{multi:true})
提示:如果不加后面的参数,则只更新符合条件的第一条记录。
(4)列值增长的修改
如果我们想实现对某列值在原有值的基础上进行增加或减少,可以使用 $inc 运算符来实现。
现在我们需要将名叫赵四的年龄增长1岁,命令如下:
db.mymogodb.update({name:"赵四"},{$inc:{age:1}})
3.3.4、删除文档
删除文档的语法结构
db.集合名.remove(条件)
(1)全部删除
db.mymongodb.remove({})
(2)删除指定数据
删除_id为646ca1ac4abb1f18327276b7的数据
db.mymongodb.remove({_id:ObjectId("646ca1ac4abb1f18327276b7")})
3.4、文档的分页查询
3.4.1、统计查询
db.集合名.count(query, options)
Parameter
Type
Description
query
document
查询选择条件。
options
document
可选。用于修改计数的额外选项。
(1)统计所有记录数
db.集合名.count()
(2)按条件统计记录数
db.comment.count({age:25})
3.4.2、分页列表查询
可以使用 limit() 方法来读取指定数量的数据,使用 skip() 方法来跳过指定数量的数据。
基本语法如下所示:
db.集合名.find().limit(NUMBER).skip(NUMBER)
如果你想返回指定条数的记录,可以在 find 方法后调用 limit 来返回结果 (TopN) ,默认值 20 ,例如:
db.mymongodb.find().limit(3)
skip 方法同样接受一个数字参数作为跳过的记录条数。(前N 个不要),默认值是0。
db.mymongodb.find().skip(3)
每页3 个,第二页开始:跳过前三条数据,接着值显示4、5、6三条数据
3.4.3、排序查询
sort() 方法对数据进行排序, sort() 方法可以通过参数指定排序的字段,并使用 1 和 -1 来指定排序的方式,其中 1 为升序排列,而 -1 是用 于降序排列。
db.COLLECTION_NAME.find().sort({KEY:1})
或
db.集合名称.find().sort(排序方式)
对name进行 降序排列,并对age进行升序排列
db.mymongodb.find().sort({name:-1,age:1})
提示: skip(), limilt(), sort()三个放在一起执行的时候,执行的顺序是先 sort(), 然后是 skip() ,最后是显示的 limit() ,和命令编写顺序无关。
3.5、文档的其他查询
3.5.1、正则的复杂条件查询
MongoDB 的模糊查询是通过 正则表达式 的方式实现的。格式为:
db.collection.find({field:/正则表达式/})
或
db.集合.find({字段:/正则表达式/})
提示:正则表达式是 js 的语法,直接量的写法。 例如,我要查询name包含"宋 " 的所有文档,代码如下:
db.comment.find({name:/宋/})
如果要查询name的内容中以"张"开头的
db.mymongodb.find({name:/^张/})
3.5.2、比较查询
这个操作符也是很常用的,格式如下 :
db.集合名称.find({ "field" : { $gt: value }}) // 大于: field > value
db.集合名称.find({ "field" : { $lt: value }}) // 小于: field < value
db.集合名称.find({ "field" : { $gte: value }}) // 大于等于: field >= value
db.集合名称.find({ "field" : { $lte: value }}) // 小于等于: field <= value db.集合名称.find({ "field" : { $ne: }}) 不等于: field !="value</code"></=>
查询age大于 20 的记录
db.mymongodb.find({age:{$gt:30}})
3.5.3、包含查询
包含使用 $in 操作符。 示例:查询数据的集合中 name 字段包含宋江 或张飞 的文档
db.mymongodb.find({name:{$in:['宋江','张飞']}})
3.5.4、条件连接查询
我们如果需要查询同时满足两个以上条件,需要使用 $and 操作符将条件进行关联。(相 当于 SQL 的 and ) 格式为:
$and:[ { },{ },{ } ]
示例:查询评论集合中 age 大于等于20 并且小于35 的文档:
db.mymongodb.find({$and:[{age:{$gte:20}},{age:{$lt:35}}]})
如果两个以上条件之间是或者的关系,我们使用 操作符进行关联,与前面and 的使用方式相同
查询评论集合中name 姓张 ,或者age小于30 的文档记录
db.mymongodb.find({$or:[{name:/^张/},{age:{$lt:30}}]})
3.6、常用命令小结
选择切换数据库:use articledb
插入数据:db.comment.insert({bson数据})
查询所有数据:db.comment.find();
条件查询数据:db.comment.find({条件})
查询符合条件的第一条记录:db.comment.findOne({条件})
查询符合条件的前几条记录:db.comment.find({条件}).limit(条数)
查询符合条件的跳过的记录:db.comment.find({条件}).skip(条数)
修改数据:db.comment.update({条件},{修改后的数据}) 或db.comment.update({条件},{$set:{要修改部分的字段:数据})
修改数据并自增某字段值:db.comment.update({条件},{$inc:{自增的字段:步进值}})
删除数据:db.comment.remove({条件})
统计查询:db.comment.count({条件})
模糊查询:db.comment.find({字段名:/正则表达式/})
条件比较运算:db.comment.find({字段名:{$gt:值}})
包含查询:db.comment.find({字段名:{$in:[值1,值2]}})或db.comment.find({字段名:{$nin:[值1,值2]}})
条件连接查询:db.comment.find({$and:[{条件1},{条件2}]})或db.comment.find({$or:[{条件1},{条件2}]})
关注夏壹分享发送:资源 获取238本进阶书籍和大厂面试