MongoDB

1 简介

说明: 支持的数据结构非常松散,是一种类似于JSON叫BSON;MongoDB中的记录是一个文档,由字段和值(field:value)组成的数据结构。一个文档就相当于一个JSON对象。field是字符型,value除了基本类型外还可以是文档、普通数组和文档数组。

作用: 解决关系型数据库(如MySQL),面对三高(高并发读写、海量数据高效率存储和访问、数据库高扩展性和高可用)需求的力不从心。

应用场景:

  1. 社交场景,存储用户及用户发表的朋友圈信息,通过地理位置索引实现附近的人、地点等功能。
  2. 游戏场景,存储用户及用户装备积分等信息,以内嵌文档的形式存储,方便查询、高效率存储和访问
  3. 物流场景,存在订单信息,订单状态是不断更新的,以内嵌数据的形式存储,一次查询就能读取订单的所有变更记录
  4. 视频直播,存储用户及点赞互动信息。

以上应用场景共同点:

  • 数据量大
  • 读写频繁
  • 数据价值较低,对事务要求不高

什么时候选择

  • 应用不需要事务支持
  • 项目需求无法确定,数据模型会变(即字段不固定)
  • 存储量大
  • 需要99.999%高可用
  • 需要大量地理位置、文本查询

1.1 与MySQL对比

在这里插入图片描述
在这里插入图片描述

docker安装mongodb
Navicat显示默认系统数据库

1.2 默认的三个数据库

  • admin: root数据库,如果将用户添加到该数据库,则默认继承所有数据库权限。相当于用户添加到该数据库则自动成为管理员。
  • local: 集群时,该数据库不会被其他数据库所复制,可以用于存储仅限于本台服务器的任意集合。
  • config: 当Mongo用于分片设置时,config数据库在内部使用,用于保存分片的相关信息。

数据库名.dropDatabase()用于删除数据库。

1.3 基本命令

  1. docker进入mongodb界面docker exec -it mongodb mongosh
  2. 用户登录use admindb.auth(“root”, “root”)
  3. 列出数据库show dbs
  4. 新建/打开数据库use testdb(如果有就打开,没有就新建)
  5. 查看当前正在使用的数据库db
  6. 查看当前库中的表show collections或者show tables
  7. 集合显式创建db.createCollection("集合名")
  8. 隐式创建是,向一个集合插入文档时,如果集合不存在,会自动创建(常用)
  9. 删除集合db.集合名.drop()

2 文档的CRUD

2.1 新增文档

insert()save()等价

db.collection.insert(
	<document or array of documents>,
	{
		writeConcern: 性能级别,
		orderd: <bolean>按顺序插入文档
	}
)

eg: 向comment集合中插入一条文档:

db.comment.insert({"articleid":"100000","content":"今天天气真好,阳光明
媚","userid":"1001","nickname":"Rose","createdatetime":new Date(),"likenum":NumberInt(10),"state":null})

注:
1)comment集合如果不存在,则会隐式创建
2)mongo中的数字,默认情况下是double类型,如果要存整型,必须使用函数NumberInt(整型数字),否则取出来就有问题了。
3)插入当前日期使用 new Date()
4)插入的数据没有指定 _id ,会自动生成主键值
5)如果某字段没值,可以赋值为null,或不写该字段。

批量插入,用[]包含多个文档,文档间用,分隔

db.comment.insertMany([
{"_id":"1","articleid":"100001","content":"我们不应该把清晨浪费在手机上,健康很重要,一杯温水幸福你我
他。","userid":"1002","nickname":"相忘于江湖","createdatetime":new Date("2019-08-
05T22:08:15.522Z"),"likenum":NumberInt(1000),"state":"1"},
{"_id":"2","articleid":"100001","content":"我夏天空腹喝凉开水,冬天喝温开水","userid":"1005","nickname":"伊人憔
悴","createdatetime":new Date("2019-08-05T23:58:51.485Z"),"likenum":NumberInt(888),"state":"1"},
{"_id":"3","articleid":"100001","content":"我一直喝凉开水,冬天夏天都喝。","userid":"1004","nickname":"杰克船
长","createdatetime":new Date("2019-08-06T01:05:06.321Z"),"likenum":NumberInt(666),"state":"1"},
{"_id":"4","articleid":"100001","content":"专家说不能空腹吃饭,影响健康。","userid":"1003","nickname":"凯
撒","createdatetime":new Date("2019-08-06T08:18:35.288Z"),"likenum":NumberInt(2000),"state":"1"},
{"_id":"5","articleid":"100001","content":"研究表明,刚烧开的水千万不能喝,因为烫
嘴。","userid":"1003","nickname":"凯撒","createdatetime":new Date("2019-08-
06T11:01:02.521Z"),"likenum":NumberInt(3000),"state":"1"}
]);

注:如果某条数据插入失败,将会终止插入,但已经插入成功的数据不会回滚掉。

2.2 删除文档

db.collection.remove(条件)

eg:

  1. 删除集合中所有的文档
    db.comment.remove({})
  2. 删除name张三的记录
    db.comment.remove({name:"张三"})

2.3 修改文档

db.collection.update(query, update, options)
//或
db.collection.update(
	<query>,
	<update>,
	{
		upsert: <boolean>,
		multi: <boolean>,
		writeConcern: <document>,
		collation: <document>,
		arrayFilters: [ <filterdocument1>, ... ],
		hint: <document|string> // Available starting in MongoDB 4.2
	}
)
ParameterTypeDescription
querydocument更新的选择条件。可以使用与find()方法中相同的查询选择器,类似sql update查询内where后面部分。在3.0版中进行了更改:当使用upsert:true执行update()时,如果查询使用点表示法在_id字段上指定条件,则MongoDB将拒绝插入新文档。
updatedocument 或者pipeline更新的内容
upsertboolean可选。如果设置为true,则在没有与查询条件匹配的文档时创建新文档。默认值为false,如果找不到匹配项,则不会插入新文档。
multiboolean可选。如果设置为true,则更新符合查询条件的多个文档。如果设置为false,则更新一个文档。默认值为false。

eg:

  1. 覆盖的修改
    将_id为1的文档的点赞量修改为1001。
    执行后,会发现这条文档除了likenum字段其它字段都不见了。
db.comment.update({_id:"1"},{likenum:NumberInt(1001)})
  1. 局部修改
    为了解决这个问题,我们需要使用修改器$set来实现,这样其他未修改的字段就不会被覆盖。
    将_id为2的记录的浏览量修改为888
db.comment.update({_id:"2"},{$set:{likenum:NumberInt(889)}})
  1. 批量修改(multi
    更新所有age为19的用户名为张三
//默认只修改第一条数据
db.comment.update({age:NumberInt(19)},{$set:{name:"张三"}})
//修改所有符合条件的数据
db.comment.update({age:NumberInt(19)},{$set:{name:"张三"}},{multi:true})
  1. 原有值的基础上做增量修改
    使用$inc运算符实现
    将_id为3的点赞数增加3个
db.comment.update({_id:"3"},{$inc:{likenum:NumberInt(1)}})

2.4 查询文档

db.collection.find(<query>, [projection])
ParameterTypeDescription
querydocument可选。使用查询运算符指定选择筛选器。若要返回集合中的所有文档,请省略此参数或传递空文档( {} )。
projectiondocument可选。指定要在与查询筛选器匹配的文档中返回的字段(投影)。若要返回匹配文档中的所有字段,请省略此参数。

eg: 查询所有

db.comment.find()
或
db.comment.find({})

eg: 条件查询

db.comment.find({userid:'1003'})

eg: 条件查询只想要第一条数据

db.comment.findOne({userid:'1003'})

投影查询
查询结果不显示所有字段,只显示指定字段(_id默认显示)
eg: 查询所有数据,但只显示_id、userid、name

db.comment.find({},{userid:1,name:1})

eg: 查询userid为1001的文档,但只显示userid、name,不显示_id

db.comment.find({userid:"1001"},{userid:1,nickname:1,_id:0})

3 文档分页查询

3.1 count查询

db.collection.count(query, options)
ParameterTypeDescription
querydocument查询条件
optionsdocument可选项,暂时不可用

eg:

  1. 统计集合的所有文档数
    db.comment.count()
  2. 统计集中中age为19的文档数
    db.comment.count({age:NumberInt(19)})

3.2 分页查询

db.COLLECTION_NAME.find().limit(NUMBER).skip(NUMBER)

使用limit()方法来读取指定数量的数据,使用skip()方法来跳过指定数量的数据。

eg:

  1. 返回前7条数据(limit(TopN)为空,默认值为20)
    db.comment.find().limit(3)
  2. 前N条记录跳过,默认值为0
    db.comment.find().skip(3)
  3. 分页查询:每页显示2条数据
//第一页,每页显示2条,跳过0条
db.comment.find().limit(2).skip(0)
//第二页,每页显示2条,跳过整个文档的前两条
db.comment.find().limit(2).skip(2)
//第三页,每页显示2条,跳过整个文档的前4条
db.comment.find().limit(2).skip(4)

3.3 排序查询

db.COLLECTION_NAME.find().sort({KEY:1})
或
db.COLLECTION_NAME.find().sort(排序方式)

sort()内指定排序字段,1表示升序,-1表示降序
eg:
对userid降序排序,如果相同则使用likenum升序排序
db.comment.find().sort({userid:-1,likenum:1})

注:skip、limit、sort的优先级:sort()>skip()>limit(),该优先级和语句的顺序无关。

4 文档其他查询

4.1 模糊查询

正则可以实现模糊查询,使用的js语法,格式为:

db.collection.find({field:/正则表达式/})
或
db.集合.find({字段:/正则表达式/})

eg:

  1. 查询content中包含"开水"的所有文档,类似于%开水%
    db.comment.find({content:/开水/})
  2. 查询content中以"开水”开头的所有文档
    db.comment.find({content:/^开水/})

4.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: value }}) // 不等于: field != value

4.3 包含查询

包含使用$in操作符,不包含使用$nin操作符。
eg:

  1. 查询userid中包含1003和1004的所有文档
    db.comment.find({userid:{$in:["1003","1004"]}})
  2. 查询userid中不包含1003和1004的所有文档
    db.comment.find({userid:{$nin:["1003","1004"]}})

4.4 and和or查询

相当于SQL的where xxx and xxx
$and:[ { },{ },{ } ]

eg:
查询likenum>=700并且<2000的所有文档
db.comment.find({$and:[{likenum:{$gte:NumberInt(700)}},{likenum:{$lt:NumberInt(2000)}}]})

$or:[ { },{ },{ } ]
eg:
查询userid为1003,或者likenum<1000的所有文档
db.comment.find({$or:[ {userid:"1003"} ,{likenum:{$lt:1000} }]})

5 索引

索引提高查询效率,MongoDB使用B-Tree。

5.1 单字段索引

对单个字段建立升序/降序索引(具体是ASC还是DESC不重要,Mongo可以从任何方向遍历索引)

5.2 复合索引

多个字段来进行排序索引,比如{userid:1,score:-1}

5.3 其他索引

地理空间索引(Geospatial Index)、文本索引(Text Indexes)、哈希索引(Hashed Indexes)。

地理空间索引(Geospatial Index)
为了支持对地理空间坐标数据的有效查询,MongoDB提供了两种特殊的索引:返回结果时使用平面几何的二维索引和返回结果时使用球面几何的二维球面索引。

文本索引(Text Indexes)
MongoDB提供了一种文本索引类型,支持在集合中搜索字符串内容。这些文本索引不存储特定于语言的停止词(例如“the”、“a”、“or”),而将集合中的词作为词干,只存储根词。

哈希索引(Hashed Indexes)
为了支持基于散列的分片,MongoDB提供了散列索引类型,它对字段值的散列进行索引。这些索引在其范围内的值分布更加随机,但只支持相等匹配,不支持基于范围的查询。

5.4 索引语句

  1. 创建索引
db.collection.createIndex(keys, options)
ParameterTypeDescription
keysdocument包含字段和值对的文档,其中字段是索引键,值描述该字段的索引类型。对于字段上的升序索引,请指定值1;对于降序索引,请指定值-1。
optionsdocument可选

eg:
单个索引

db.comment.createIndex({userid:1})
返回结果:
{
	"createdCollectionAutomatically" : false,
	"numIndexesBefore" : 1,
	"numIndexesAfter" : 2,
	"ok" : 1
}

复合索引

db.comment.createIndex({userid:1,nickname:-1})
返回结果:
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 2,
"numIndexesAfter" : 3,
"ok" : 1
}
  1. 查看索引
db.collection.getIndexes()

注:MongoDB 3.0+才行

  1. 移除索引
    移除指定索引:
db.collection.dropIndex(index)
ParameterTypeDescription
indexString 或者 ducoment指定删除的索引。可以是索引名或者创建时的索引文档(删除文本索引需要指定索引名)

eg:
删除comment集合中userid字段上的升序索引

db.comment.dropIndex({userid:1})

移除集合中所有的索引:

db.comment.dropIndexes()

注:_id 的字段的索引是无法删除的,只能删除非 _id 字段的索引。

6 MongoTemplate

Spring Boot 使用 MongoTemplate 操作 MongoDB
springboot MongoTemplate 之Criteria+Query实现常见操作
MongoDB学习02:使用MongoTemplate操作MongoDB
MongoTemplate的基本使用方法

MongoTemplate更新实体类

1.了解Spring 2.了解NoSQL和文档数据库 3.要求 4.其他帮助资源 4.1。支持 4.1.1。社区论坛 4.1.2。专业支持 4.2。发展之后 5.新&值得注意的 5.1。Spring Data MongoDB 2.1中的新特性 5.2。Spring Data MongoDB 2.0中的新特性 5.3。Spring Data MongoDB 1.10中的新特性 5.4。Spring Data MongoDB 1.9中的新特性 5.5。Spring Data MongoDB 1.8中的新特性 5.6。Spring Data MongoDB 1.7中有什么新功能 6.依赖 6.1。Spring Boot的依赖管理 6.2。Spring框架 7.使用Spring Data Repositories 7.1。核心概念 7.2。查询方法 7.3。定义存储库接口 7.3.1。微调储存库定义 7.3.2。空处理存储库方法 7.3.3。将存储库与多个Spring Data模块一起使用 7.4。定义查询方法 7.4.1。查询查询策略 7.4.2。查询创建 7.4.3。属性表达式 7.4.4。特殊参数处理 7.4.5。限制查询结果 7.4.6。流式查询结果 7.4.7。异步查询结果 7.5。创建存储库实例 7.5.1。XML配置 7.5.2。JavaConfig 7.5.3。独立使用 7.6。Spring Data存储库的自定义实现 7.6.1。定制个人存储库 7.6.2。自定义基础存储库 7.7。从聚合根发布事件 7.8。Spring数据扩展 7.8.1。Querydsl扩展 7.8.2。Web支持 7.8.3。存储库填充程序 7.8.4。传统网络支持 参考文档 8.介绍 8.1。文档结构 9. MongoDB支持 9.1。入门 9.2。示例存储库 9.3。用Spring连接到MongoDB 9.3.1。使用基于Java的元数据注册Mongo实例 9.3.2。使用基于XML的元数据注册Mongo实例 9.3.3。MongoDbFactory接口 9.3.4。使用基于Java的元数据注册MongoDbFactory实例 9.3.5。使用基于XML的元数据注册MongoDbFactory实例 9.4。MongoTemplate简介 9.4.1。实例化MongoTemplate 9.4.2。WriteResultChecking策略 9.4.3。WriteConcern 9.4.4。WriteConcernResolver 9.5。保存,更新和删除文档 9.5.1。如何_id在映射图层中处理该字段 9.5.2。类型映射 9.5.3。保存和插入文件的方法 9.5.4。更新集合中的文档 9.5.5。在集合中插入文档 9.5.6。在集合中查找和插入文档 9.5.7。删除文件的方法 9.5.8。乐观锁定 9.6。查询文件 9.6.1。查询集合中的文档 9.6.2。查询文件的方法 9.6.3。查询不同的值 9.6.4。地理空间查询 9.6.5。GeoJSON支持 9.6.6。全文查询 9.6.7。排序规则 9.6.8。JSON模式 9.6.9。流利的模板API 9.7。按实例查询 9.7.1。介绍 9.7.2。用法 9.7.3。示例匹配器 9.7.4。执行一个例子 9.7.5。无类型示例 9.8。减少地图操作 9.8.1。使用示例 9.9。脚本操作 9.9.1。使用示例 9.10。集团运营 9.10.1。使用示例 9.11。聚合框架支持 9.11.1。基本概念 9.11.2。支持的聚合操作 9.11.3。投影表达式 9.11.4。分面分类 9.12。用自定义转换器覆盖默认映射 9.12.1。使用已注册的Spring Converter进行保存 9.12.2。使用Spring转换器读取 9.12.3。使用MongoConverter注册Spring转换器 9.12.4。转换器消除歧义 9.13。索引和集合管理 9.13.1。创建索引的方法 9.13.2。访问索引信息 9.13.3。使用集合的方法 9.14。执行命令 9.14.1。执行命令的方法 9.15。生命周期事件 9.16。例外翻译 9.17。执行回调 9.18。GridFS支持 9.19。更改流 9.19.1。使用MessageListener更改流 9.19.2。更改流 - 无效 10.反应性的MongoDB支持 10.1。入门 10.2。使用Spring和Reactive Streams Driver连接到MongoDB 10.2.1。使用基于Java的元数据注册MongoClient实例 10.2.2。ReactiveMongoDatabaseFactory接口 10.2.3。使用基于
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值