文章目录
Mongodb
MongoDB 是一个基于分布式文件存储的数据库。由 C++语言编写,旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。
MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。它支持的数据结构非常松散,是类似 json 的 bson ( json 的二进制 ) 格式,因此可以存储比较复杂的数据类型。Mongo 最大的特点是它支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。
MongoDB 结构,最小的单位为文档(类似 MySQL 的行),每一个文档用的是 BSON 形式来存储(类似 JSON),文档的上一层为集合(类似 MySQL 的表),再上一级为库(类似MySQL 的数据库)。
1 安装及相关概念
1.1 docker 安装
搜索:docker search mongodb
拉取镜像:docker pull docker.io/mongo
查看:docker images
启动容器:
docker run -d --name mongodb -v /var/mongodb/data:/data/db -v /var/mongodb/backup:/data/backup -v /var/mongodb/conf:/data/configdb -p 27017:27017 docker.io/mongo --auth
创建用户和密码:(默认没有用户授权,在实际企业开发中,必须增加账户和密码,否则有入侵风险)
1.登录mongodb:docker exec -it mongodb mongo
2.use admin(需要绑定当前的数据库)
3.创建对应的管理员和相关信息:db.createUser({user:“admin”,pwd:“123123”,roles:[“root”]})
(root表示超级管理员)
角色说明:
4.验证:db.auth(“admin”,“123123”)
可以用相同方式创建其他用户,要创建对应的数据库用户,需要先use对应的数据库。
查看用户信息:show users
开启远程访问
进入mongodb容器:docker exec -it mongodb /bin/bash
直接编辑(先安装vim):apt-get update,apt-get install vim
vim /etc/mongodb.conf.orig
客户端连接mongodb
利用 robomongo 进行连接
1.2 相关概念
在 mongodb 中基本的概念是文档、集合、数据库
2 Mongodb命令
2.1 基础命令
1.版本:db.version()
2.状态:db.stats()
3.连接信息:db.getMongo()
4.显示所有数据库:
docker exec -it mongodb mongo admin
db.auth(“admin”,“123123”)
show dbs;
5.选库:use lxy;
Mongodb的库是隐式创建,你可以use 一个不存在的库,然后在该库下创建 collection,即可创建库
6.创建collection
db.createCollection(“集合名字”)
也支持隐式创建,直接向一个不存在的集合插入数据,即可自动创建。
db.collectionName.insert(document);
db.admin.insert({name:“超级管理员”})——自动创建admin集合
7.查看所有集合:show tables/collections;
8.删除集合:db.collectionName.drop();
db.admin.drop();
9.删除数据库:db.dropDatabase()
2.2 增删改查
1 增-insert
db.collectionName.insert(document)
增加单个文档:db.user.insert({name:“tom”,age:12,gender:“boy”});
增加单个文档,并指定_id:db.user.insert({_id:10,name:“licy”});
增加多个文档:db.user.insert([{_id:9,name:“rose”},{name:“jack”,age:13}]);——json对象数组
2 查-find,findOne
db.collectionName.find(查询表达式,查询的列)
db.collectionName.find(表达式,{列 1:1,列 2:1});
db.collectionName.find().pretty(): 格式化查询
查询条数:db.collectionName.find().count()
eg:db.user.find().count()
查询所有,所有字段:db.collectionName.find()
db.user.find();db.user.findOne();
查询所有,指定列:db.collectionName.find({},{列1:1,列2:1})
注意_id是默认查询出来的:db.user.find({},{name:1}),db.user.find({},{name:1,age:1})
不存在的列不会显示出来
如果不想查询出_id,就需要将列_id:0——db.user.find({},{name:1,age:1,gender:1,_id:0})
列对应的数字的含义:1:显示——0:不显示
3 查询表达式
- 指定表达式查询:
db.user.find({gender:“boy”},{name:1,gender:1}):查询所有性别为boy的文档,只显示name,gender - 简单查询表达式:
{filed:value},是指查询field列的值为value的文档 - $ ne
{field:{$ ne:value}}:查询filed列的值不等于value的文档
db.user.find({gender:{$ne:“boy”}}):查询性别不等于boy的 - $ nin
not in 和mysql一致{field:{$ nin:[value1,value2]}}
db.user.find({gender:{$nin:[“boy”,“girl”]}}); - $ all
{field:{$ all:[v1,v2…]}}:是指取出的field列是一个数组,且至少包含v1,v2值
db.user.find({like:{$all:[“rap”,“sing”]}}):like中至少包含rap,sing的 - exists
{field:{$ exists:1}}:1包含——0不包含
作用:查询出含有field字段的文档
db.user.find({gender:{$ exists:1}}):包含gender的
db.user.find({like:{$ exists:0}}):不包含like的 - $ nor
{$ nor:[条件1,条件2]}:是指返回所有条件都不满足的文档
db.user.find({$nor:[{gender:“boy”},{gender:“girl”}]}):性别不男不女 - 正则表达式
db.user.find({name:/i/}):包含i
db.user.find({name:/.*i$/}):以i结束 - $ where
db.user.find({$ where:“this.name== ‘tom’ II this.name=='lucy”}):查询名字等于tom或lucy的文档
注意:用$where查询时, mongodb是把bson结构的二进制数据转换为json结构的对象,然后比较对象的属性是否满足表达式,速度较慢。
比较符
> 大于 $gt
< 小于 $lt
>= 大于等于 $gte
<= 小于等于 $lte
4 删-remove
db.collectionName.remove(查询表达式,选项);
选项是指{ustOne:true/false},是否只删一行,默认为falsel
注意:
1:查询表达式依然是个json对象
2:查询表达式匹配的行将被删掉
3:如果不写查询表达式,collections中的所有文档将被删掉
db.user.remove({name:“tom”}):将所有name=tom的文档都删除掉
db.user.remove({name:“tom”},true):只会删除一行
5 改-update
语法: db.collection.update(查询表达式,新值,选项);
改谁? ---------------查询表达式
改成什么样? ------新值或赋值表达式
操作选项?----------可选参数
db.user.update({name:‘jack’},{name:‘hsj’}):选中user表中,name值为jack的文档,并把其文档值改为{name:‘hsj’}
结果:文档中的其他列也不见了,改后只有_id 和name列了,即新文档直接替换了旧文档,而不是修改。
如果是想修改文档的某列,可以用$ set关键字
db.collectionName.update(查询表达式{$ set:{name:‘新值’})
db.user.update({name:‘jack’},{$set:{name:‘jack222’}})
修改时的赋值表达式:
$set :修改某列的值
$unset :删除某个列
$rename :重命名某个列
$inc :增长某个列
$setOnInsert :当upsert 为true时,并且发生了insert 操作时,可以补充的字段(相当于mysql中的列的默认值)
例如:
db.user.update({name:'lsi'},{$set:{area:'chengdu'},$unset:{height:1},$inc:{age:1},$rename:{sex:'gender'})
db.user.update({name:"tom"},{$set:{name:"tom",age:13,gender:"boy"},$setOnInsert:{phone:111111},{upsert:true})
Option的作用:
{upsert:true/ false ,multi:true/false}
Upsert:
是指没有匹配的行,则直接插入该行.(和mysql中的replace 一样)
例:db.stu.update({name:'wuyong'},{$set:{name:'junshiwuyong'}},{upsert:true});
如果有name= 'wuyong'的文档将被修改,如果没有,将添加此新文档
例:db.news.update({_id:99},{x: 123.y:234,}{upsert.true});
没有_ id=99 的文档被修改,因此直接插入该文档
multi:是指修改多行(即使查询表达式命中多行,默认也只改1行,如果想改多行,可以用此选项)
例:db.news.update({age:21};{$set:{age.22};{multitrue});
则把news中所有age=21的文档都修改
2.3 游标操作
通俗的说,游标不是查询结果,而是查询的返回资源,或者接口,通过这个接口,你可以逐条读取,这里主要通过游标来做分页。
声明游标
var cursor = db.collectionName.find(表达式,列);
cursor.hasNaxt():判断游标是否已经取到尽头
cursor.Next():取出游标的下一个单元
遍历游标
while(cursor.hasNext()){printjson(cursor.next());}
cursor.forEach(回调)
var cursor = db.user.find() //声明游标
var getUser = function(obj){printjson(obj);} //定义回调函数
cursor.forEach(getUser) //遍历
2.4 分页
比如查到10000行,跳过100页,取10行。一般我们假设页容量pageSize,当前是page页,就需要跳过前(page-1)*pageSize 行,再取pageSize行。在mysql中, limit (page-1)*pageSize,pageSize来实现,在mongo中,用skip(), limit()函数来实现的。
如var mycursor = db.user.find().skip(3);则是查询结果中,跳过前3行
查询第1页,每页2条:var cursor = db,user.find(). skip(0),limit(2);
查询第2页,每页2条:var cursor = db.user.find().skip(2).limit(2);
查询第3页,每页2条:var cursor = db.user.find(). skip(4).limit(2);
注意不要随意使用toArray():会把所有的行立即以对象形式组织在内存里,可以在取出少数几行时,用此功能。
3 springboot整合mongodb
先创建读写用户:
加入依赖
< !- -mongodb-- >
< dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
配置
mongoTemplate的使用