MongoDB数据库学习总结

概述

  • mongodb一个开源的,基于分布式的,面向文档存储的非关系型数据库,是非关系型数据库当中功能最丰富、最像关系数据库的
  • 由C++语言编写的,使用JavaScript作为操作语言,是一个基于分布式文件存储的开源数据库系统
  • 将数据存储为一个文档,数据结构由键值(key=>value)对组成。MongoDB 文档类似于 JSON 对象。字段值可以包含其他文档,数组及文档数组
  • 非关系型的数据库即NoSQL:是对不同于传统的关系型数据库的数据库管理系统的统称,用于超大规模数据的存储,数据存储不需要固定的模式,无需多余操作就可以横向扩展
    • 优点
      • 高可扩展性
      • 分布式计算
      • 架构的灵活性,半结构化数据
      • 没有复杂的关系
      • 低成本
    • 缺点
      • 没有标准化
      • 有限的查询功能
      • 最终一致是不直观的程序

数据库常规操作

帮助命令

help

创建数据库

use server1
db.server1.insert(obj);
//注:数据库创建,必须要插入一条数据后,show dbs命令才会显示,数据库已经添加

查看数据库

show dbs//查看所有数据库或show databases
db//查看当前数据库
//注:这个操作并不会显示系统所有的数据库,而只显示当前登录用户被授权的数据库

删除数据库

db.dropDatabase()//删除当前数据库

切换数据库

use 数据库名

创建集合

db.createCollection(name, options)//name: 要创建的集合名称,options: 可选参数, 指定有关内存大小及索引的选项:db.createCollection("mycol", { capped : true, autoIndexId : true, size : 6142800, max : 10000 } )
//capped:如果为 true,则创建固定集合。固定集合是指有着固定大小的集合,当达到最大值时,它会自动覆盖最早的文档。 当该值为 true 时,必须指定 size 参数
//autoIndexId:如为 true,自动在 _id 字段创建索引。默认为 false
//size:为固定集合指定一个最大值(以字节计)。 如果 capped 为 true,也需要指定该字段
//max:指定固定集合中包含文档的最大数量

查看集合

show collections

删除集合

db.collection.drop()
//清屏命令:cls

插入文档

db.COLLECTION_NAME.insert(document) //主键存在,则异常提示重复,不保存文档
db.COLLECTION_NAME.save(document) //主键存在则替换,如果文档不存在就是添加
db.COLLECTION_NAME.insertOne({"b": 3}) //参数只能是单条
db.COLLECTION_NAME.insertMany([{"b": 3}, {'c': 4}]) //参数只能是数组

查询文档

db.collection.find(query, projection)
  • query:可选,使用查询操作符指定查询条件
操作格式范例RDBMS中的类似语句
等于{:}db.col.find({“by”:“菜鸟教程”}).pretty()where by = ‘菜鸟教程’
小于{:{$lt:}}db.col.find({“likes”:{$lt:50}}).pretty()where likes < 50
小于或等于{:{$lte:}}db.col.find({“likes”:{$lte:50}}).pretty()where likes <= 50
大于{:{$gt:}}db.col.find({“likes”:{$gt:50}}).pretty()where likes > 50
大于或等于{:{$gte:}}db.col.find({“likes”:{$gte:50}}).pretty()where likes >= 50
不等于{:{$ne:}}db.col.find({“likes”:{$ne:50}}).pretty()where likes != 50
数据类型{:{$type:<number/string>}}db.col.find({“likes”:{$type:1}}).pretty()where likes != 50
in{:{$in:[value]}}db.col.find({“likes”:{$in:[1,2]}}).pretty()where likes in (1,2)
and{:{$and:[{对象1:{条件},对象2:{条件}]}}或{:{对象1:{条件1,条件2}}}db.col.find({$and:[{条件1},{条件2}]}).pretty()where 条件1 and 条件2
or语法与and相同
not{:{$not:{对象:null}}db.col.find($not:{like:null})where like is not null
null{:{对象:null}db.col.find({like:null})where like=null
使用正则db.col.find({title:/^教/})
  • projection:可选,使用投影操作符指定返回的键。查询时返回文档中所有键值, 只需省略该参数即可(默认省略)
    • 返回指定字段和_id字段:在结果集中,只有item和qty字段,默认_id字段也是返回的。代码如下:db.inventory.find( { type: ‘food’}, { item: 1, qty: 1} )
    • 仅返回指定字段:可以通过在projection中指定排除_id字段将其从结果中去掉。代码如下:db.inventory.find( { type: ‘food’}, { item: 1, qty:1, _id:0} )
    • 返回除排除掉以外的字段:可以使用一个projection排除一个或者一组字段,如下: 代码如下:db.inventory.find( { type: ‘food’}, { type:0} )8
  • 注:如果你需要以易读的方式来读取数据,可以使用 pretty() 方法,pretty() 方法以格式化的方式来显示所有文档

更新文档

db.collection.update(
   <query>,
   <update>,
   {
     upsert: <boolean>,
     multi: <boolean>,
     writeConcern: <document>
   }
)
db.collection.updateOne(参数与上同)//更新符合条件的第一条
db.collection.updateOne(参数与上同)//更新所有符合条件的数据
  • query : update的查询条件,类似sql update查询内where后面的,规则与查询部分相同
  • update : update的对象和一些更新的操作符(如[Math Processing Error],inc…)等,也可以理解为sql update查询内set后面的
    • 例:db.col.update({‘title’:‘MongoDB 教程’},{$set:{‘title’:‘MongoDB’}})
    • 操作符
      • $inc:{ $inc : { field : value } }。意思对一个数字字段field增加value
      • $set:{ $set : { field : value } }。赋值语句
      • $unset:{ $unset : { field : 任意内容} }。就是删除field字段
      • $push:{ $push : { field : value } }。把value追加到field里面去,field一定要是数组类型才行,如果field不存在,会新增一个数组类型加进去
      • $pushAll:{ $pushAll : { field : value_array } }。将数组中的每一项,追加多个值到一个数组字段内
      • $addToSet:{ $addToSet : { field : value } }。增加一个值到数组内,而且只有当这个值不在数组内才增加
      • $pop:{ $pop : { field : 1 } } 删除最后一个值,{ $pop : { field : -1 } }删除第一个值
      • $pull:{ $pull : { field : value } }。从数组field内删除一个等于value值
      • $pullAll:{ $pullAll : { field : value_array } }。可以一次删除数组内的多个值
      • $是他自己的意思,代表按条件找出的数组里面某项他自己
  • upsert : 可选,这个参数的意思是,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入
  • multi : 可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新
  • writeConcern :可选,抛出异常的级别
    • WriteConcern.NONE:没有异常抛出
    • WriteConcern.NORMAL:仅抛出网络错误异常,没有服务器错误异常
    • WriteConcern.SAFE:抛出网络错误异常、服务器错误异常;并等待服务器完成写操作
    • WriteConcern.MAJORITY: 抛出网络错误异常、服务器错误异常;并等待一个主服务器完成写操作
    • WriteConcern.FSYNC_SAFE: 抛出网络错误异常、服务器错误异常;写操作等待服务器将数据刷新到磁盘
    • WriteConcern.JOURNAL_SAFE:抛出网络错误异常、服务器错误异常;写操作等待服务器提交到磁盘的日志文件
    • WriteConcern.REPLICAS_SAFE:抛出网络错误异常、服务器错误异常;等待至少2台服务器完成写操作

删除文档

db.collection.remove(
   <query>,
   {
     justOne: <boolean>,
     writeConcern: <document>
   }
)
db.collection.deleteOne() //删除符合条件的第一条
db.collection.deleteMany() //删除所有符合条件的数据
  • query :(可选)删除的文档的条件
  • justOne : (可选)如果设为 true 或 1,则只删除一个文档,如果不设置该参数,或使用默认值 false,则删除所有匹配条件的文档
  • writeConcern :(可选)抛出异常的级别

分页

db.COLLECTION_NAME.find().limit(NUMBER).skip(NUMBER)
// limit限制输出个数,skip跳过输出个数。两者可以单独使用也可以结合使用

总数

db.COLLECTION_NAME.find().count()

排序

db.COLLECTION_NAME.find().sort({title:-1,likes:1}) //对象的第一个属性为主排序,主排序相同的内容再实现后面属性的排序
//注:skip(), limilt(), sort() 三个放在一起执行的时候,执行的顺序是先 sort(), 然后是 skip(),最后是显示的 limit()

索引

db.collection.createIndex(keys, options) //keys对象参数为1表示正序建立索引,-1表示逆序建立索引。如果添加多个属性为联合索引
  • options
options参数Type描述
backgroundBoolean建索引过程会阻塞其它数据库操作,background可指定以后台方式创建索引,即增加 “background” 可选参数。 “background” 默认值为false
uniqueBoolean建立的索引是否唯一。指定为true创建唯一索引。默认值为false.
namestring索引的名称。如果未指定,MongoDB的通过连接索引的字段名和排序顺序生成一个索引名称。用于索引删除
sparseBoolean对文档中不存在的字段数据不启用索引;这个参数需要特别注意,如果设置为true的话,在索引字段中不会查询出不包含对应字段的文档.。默认值为 false.
expireAfterSecondsinteger指定一个以秒为单位的数值,完成 TTL设定,设定集合的生存时间
vindex version索引的版本号。默认的索引版本取决于mongod创建索引时运行的版本
weightsdocument索引权重值,数值在 1 到 99,999 之间,表示该索引相对于其他索引字段的得分权重
default_languagestring对于文本索引,该参数决定了停用词及词干和词器的规则的列表。 默认为英语
language_overridestring对于文本索引,该参数指定了包含在文档中的字段名,语言覆盖默认的language,默认值为 language
  • 查看集合索引
    • db.col.getIndexes()
  • 查看集合索引大小
    • db.col.totalIndexSize()
  • 删除集合所有索引
    • db.col.dropIndexes()
  • 删除集合指定索引
    • db.col.dropIndex(“索引名称”)
  • 设置定时删除任务
    • db.col.createIndex({“createDate”: 1},{expireAfterSeconds: 180}) // 在数据记录中 createDate 为日期类型之后180删除
    • 索引关键字段必须是 Date 类型
    • 非立即执行:扫描 Document 过期数据并删除是独立线程执行,默认 60s 扫描一次,删除也不一定是立即删除成功
    • 单字段索引,混合索引不支持

数据库高级操作

  • 当出现多个集合之间数据组织的问题时,NoSQL不像关系型数据库,通过关系来实现多数据直接的结合。要想实现多文档,多集合的管理数据,就要使用应用层来回查询。使用这种方式将会消耗大量的网络数据,不利于数据库操作的效率。

聚合

  • MongoDB中聚合的方法使用aggregate()。聚合就是可以对数据查询进行多次过滤操作,以达到复杂查询的目的。聚合查询函数接收一个数组,数组里面是若干个对象,每个对象就是一次查询的步骤。前一个查询的查询结果,作为后一个查询的筛选内容
  • 管道:将MongoDB文档在一个管道处理完毕后将结果传递给下一个管道处理,聚合就是利用多个操作(类似于sql子句),通过管道连接到一起,管道无顺序,且可以重复
  • 表达式:处理输入文档并输出。表达式是无状态的,只能用于计算当前聚合管道的文档,不能处理其它的文档
    • $ sum:计算总和(例:db.mycol.aggregate([{$ group : {_id : “$ by_user”, num_tutorial : { s u m : " sum : " sum:"likes"}}}]))
    • $avg:计算平均值
    • $min:获取集合中所有文档对应值得最小值
    • $max:获取集合中所有文档对应值得最大值
    • $push:在结果文档中插入值到一个数组中
    • $addToSet:在结果文档中插入值到一个数组中,但不创建副本
    • $first:根据资源文档的排序获取第一个文档数据
    • $last:根据资源文档的排序获取最后一个文档数据
db.getCollection("student").aggregate([
        { 
            "$match" : {
                "age" : {
                    "$gt" : 20.0
                }
            }
        }, 
        { 
            "$lookup" : {
                "from" : "room", 
                "localField" : "class", 
                "foreignField" : "name", 
                "as" : "num"
            }
        }, 
        { 
            "$unwind" : {
                "path" : "$num", 
                "includeArrayIndex" : "l", 
                "preserveNullAndEmptyArrays" : false
            }
        }, 
        { 
            "$project" : {
                "num.name" : 1.0
            }
        }, 
        { 
            "$count" : "cou"
        }
])
  • 常用的管道查询操作
    • $project:修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档,类似于select
    • $match:用于过滤数据,只输出符合条件的文档, $match使用MongoDB的标准查询操作,类似于where与having
    • $limit:用来限制MongoDB聚合管道返回的文档数,类似于limit
    • $skip:在聚合管道中跳过指定数量的文档,并返回余下的文档,类似于limit
    • $unwind:将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值
    • $group:将集合中的文档分组,可用于统计结果,类似于group by
    • $sort:将输入文档排序后输出,类似于order by
    • $geoNear:输出接近某一地理位置的有序文档
    • $lookup:连表查询,类似于select
  • $lookup
db.emp.aggregate([ 
	{
		$lookup:{ 
			from:'dept', //连接的表
			localField:'deptId', //主键
			foreignField:'id', //外键
			as:'mydept' //别名
		}
	}
]);

副本集(复制)

  • 将数据同步在多个服务器的过程,提供了数据的冗余备份,并在多个服务器上存储数据副本,提高了数据的可用性, 并可以保证数据的安全性
  • 至少需要两个节点,一个是主节点,负责处理客户端请求,其余的都是从节点,负责复制主节点上的数据,形成一主一从、一主多从的搭配方式
  • 对主节点的增删改操作会映射到从节点,从而保证从节点的数据与主节点一致。对从节点进行查询操作
  • MongoDB副本集设置
    • 创建mongoDB服务器:
    mongod --port 27017 --dbpath "D:\mongodb\data" --replSet rs0
    
    • 主节点启动一个新的副本集
    rs.initiate()
    // 查看副本集的配置:rs.conf()
    // 查看副本集状态: rs.status()
    
    • 副本集添加成员
    rs.add("localhost:27017")
    

事务

  • MongoDB4.0开始支持事务,前提必须在副本集中,必须在同一个session中
  • 获取会话:session=db.getMongo().startSession();
  • 启动事务:session.startTransaction();
  • 执行操作:session.getDatabase(“test”).user.insert({name:“ming”, age:19})
  • 事务提交:session.commitTransaction();
  • 事务回滚:session.abortTransaction();
  • 结束会话:session.endSession();

分片

  • 为满足MongoDB数据量大量增长的需求,可以通过在多台机器上分割数据,使得数据库系统能存储和处理更多的数据
  • 三个主要组件
    • Shard:用于存储实际的数据块,实际生产环境中一个shard server角色可由几台机器组个一个replica set承担,防止主机单点故障
    • Config Server:mongod实例,存储了整个 ClusterMetadata,其中包括 chunk信息
    • Query Routers:前端路由,客户端由此接入,且让整个集群看上去像单一数据库,前端应用可以透明使用

数据库备份与恢复

  • 将数据库备份成文件
mongodump -h localhost -d server1 -u server1 -p xxx --authenticationDatabase admin -o E:\log
// -h:链接主机
// -d:备份数据库名
// -u:用户名
// -p:密码
// -o:导出地址
// –authenticationDatabase admin:指定身份验证数据库
  • 将文件导入到数据库
mongorestore -h localhost -d server1 -u server1 -p xxx --authenticationDatabase admin --dir E:\log\server1
// –host <:port>, -h <:port>: MongoDB所在服务器地址,默认为: localhost:27017
// –db , -d:需要恢复的数据库实例
// –drop:恢复的时候,先删除当前数据,然后恢复备份的数据。就是说,恢复后,备份后添加修改的数据都会被删除
// –dir:指定备份的目录

结合springboot

  • maven依赖
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
  • 主配置文件
spring.data.mongodb.uri=mongodb://localhost:27017/test
  • 实体类
@Getter
@Setter
@Document(collation="user")
public class User implements Serializable {
	@Id
	private ObjectId _id;
	@Field("name")
	private String name;
	@Field("age")
	private Integer age;
	@Field("city")
	private String city;
}
  • Repository映射
@Repository
public interface UserRepository extends MongoRepository<User, ObjectId> {
//MongoRepository包含增删改查方法,详细参照jpa
//也可自定义方法,若方法名符合约定,即可实现响应功能
//find+全局修饰符(All,User,distinct,first,top)+by+字段+运算符+逻辑运算符....+排序 参数要按照条件给足,如果需要分页,增加一个参数Pageable参数
// select * from user where age>= ? and age <= ? and name like ?
public List<User> findByAgeBetweenAndNameIsLikeOOrderByAgeAsc(Integer ageStart, Integer ageEnd, String name, Pageable page);
}

mongoTemplate:可实现聚合,进行复杂操作

  • 不需要在实体类中配置Document, 需要在每一个操作中,手动添加Collection
@Autowired
private MongoTemplate mongoTemplate;
  • 常用方法

    • mongoTemplate.findOne(query,Student.class):查询Student文档的第一条
    • mongoTemplate.findAll(Student.class):查询Student文档的全部数据
    • mongoTemplate.findById(id, Student.class):查询Student文档id为id的数据
    • mongoTemplate.find(query, Student.class) : 根据query内的查询条件查询
    • mongoTemplate.upsert(query, update, Student.class):更新对象不存在则去添加
    • mongoTemplate.updateFirst(query, update, Student.class):修改查询返回结果集的第一条
    • mongoTemplate.updateMulti(query,update,Student.class):修改查询返回结果集的全部
    • mongoTemplate.remove(query, Student.class): 删除
    • mongoTemplate.save(student): 新增
  • Query对象

    • 创建一个query对象(用来封装所有条件对象),再创建一个criteria对象(用来构建条件),创建Pattern对象(用来封装正则表达式)
      • Query query = new Query();
      • Criteria criteria = new Criteria();
      • Pattern pattern= Pattern.compile(“^.“+“条件”+”.$”, Pattern.CASE_INSENSITIVE);
    • 精准条件:criteria.and(“key”).is(“条件”)
    • 模糊条件:criteria.and(“key”).regex(pattern)
    • 封装条件:query.addCriteria(criteria)
    • 大于(创建新的criteria):Criteria gt = Criteria.where(“key”).gt(“条件”)
    • 小于(创建新的criteria):Criteria lt = Criteria.where(“key”).lt(“条件”)
    • query.addCriteria(new Criteria().andOperator(gt,lt));
    • 一个query中只能有一个andOperator(),其参数也可以是Criteria数组。
    • 排序 :query.with(new Sort(Sort.Direction.ASC, “age”). and(new Sort(Sort.Direction.DESC, “date”)))
  • Update对象

    • Update update = new Update().set(“publish”, Student.getPublish()).set(“info”, Student.getInfo()).set(“参数名”, 参数值)
  • 聚合

    • 实例
    Aggregation customerAgg = Aggregation.newAggregation(
    	Aggregation.project("_id","name","city","age"),
    	Aggregation.group("city").first("name").as("name").avg("age").as("avgAge").count().as("totalNum")
    );
    AggregationResults<Map> users = mongoTemplate.aggregate(customerAgg, "user", Map.class);
    List<Map> list = users.getMappedResults();
    
    • project:列出所有本次查询的字段,包括查询条件的字段和需要搜索的字段
    • match:搜索条件criteria
    • unwind:某一个字段是集合,将该字段分解成数组
    • group:分组的字段,以及聚合相关查询
      • sum:求和(同sql查询)
      • count:数量(同sql查询)
      • avg:平均值(同sql查询)
      • as:别名(同sql查询)
      • addToSet:将符合的字段值添加到一个集合或数组中
      • first:歧义字段取第一个值
    • sort:排序
    • skip&limit:分页查询
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值