MongoDB⽂档地址: https://docs.mongodb.com/manual/
📖简介
MongoDB是⼀个 基于分布式⽂件存储的数据库 。由C++语⾔编写。旨在 为WEB 应⽤提供可扩展⾼性能数据存储解决⽅案 。 MongoDB是⼀个 介于关系数据库和⾮关系数据库 之间的产品,是⾮关系数据 库当中功能最丰富,最像关系数据库的。他⽀持的数据结构⾮常松散,是 类似json的bson格式,因此可以存储⽐较复杂的数据类型 。Mongo最⼤的 特点是他⽀持的查询语⾔⾮常强⼤,其语法有点类似于⾯向对象的查询语 ⾔, ⼏乎可以实现类似关系数据库单表查询的绝⼤部分功能,⽽且还⽀持对数据 建⽴索引。
特点
-
⾯向集合存储,易存储对象类型的数据
-
⽀持查询,以及动态查询
-
⽀持RUBY,PYTHON,JAVA,C++,PHP,C#等多种语⾔
-
⽂件存储格式为BSON(⼀种JSON的扩展)
-
⽀持复制和故障恢复和分⽚
-
⽀持事务⽀持
-
索引 聚合 关联….
应⽤场景
-
游戏应⽤:使⽤云数据库MongoDB作为游戏服务器的数据库存储⽤户信 息。⽤户的游戏装备、积分等直接以内嵌⽂档的形式存储,⽅便进⾏查 询与更新。
-
物流应⽤:使⽤云数据库MongoDB存储订单信息,订单状态在运送过程 中会不断更新,以云数据库MongoDB内嵌数组的形式来存储,⼀次查询 就能将订单所有的变更读取出来,⽅便快捷且⼀⽬了然。
-
社交应⽤:使⽤云数据库MongoDB存储⽤户信息以及⽤户发表的朋友圈 信息,通过地理位置索引实现附近的⼈、地点等功能。并且,云数据库 MongoDB⾮常适合⽤来存储聊天记录,因为它提供了⾮常丰富的查询, 并在写⼊和读取⽅⾯都相对较快。
-
视频直播:使⽤云数据库MongoDB存储⽤户信息、礼物信息等。
-
⼤数据应⽤:使⽤云数据库MongoDB作为⼤数据的云存储系统,随时进 ⾏数据提取分析,掌握⾏业动态。
🔨安装
Docker⽅式安装
-
拉取 mongodb mongodb 镜像
docker pull mongo:5.0.5
-
运行mongo镜像
docker run -d --name mongo -p 27017:27017 mongo:5.0.5
-
进⼊ mongo 容器
docker exec -it eebed9d883f0 bash
📌核心概念
库
mongodb中的库就类似于传统关系型数据库中库的概念,⽤来通过不同库隔离不 同应⽤数据 。mongodb中可以建⽴多个数据库。每⼀个库都有⾃⼰的集合 和权限,不同的数据库也放置在不同的⽂件中。默认的数据库为”test”,数 据库存储在启动指定的data⽬录中。
集合
集合就是 MongoDB ⽂档组,类似于 RDBMS (关系数据库管理系统: Relational Database Management System)中的表的概念。 集合存在于数据库中,⼀个库中可以创建多个集合。每个集合没有固定的 结构,这意味着你在对集合可以插⼊不同格式和类型的数据,但通常情况 下我们插⼊集合的数据都会有⼀定的关联性。
文档
文档集合中⼀条条记录,是⼀组键值(key-value)对(即 BSON)。MongoDB 的 ⽂档不需要设置相同的字段,并且相同的字段不需要相同的数据类型,这 与关系型数据库有很⼤的区别,也是 MongoDB ⾮常突出的特点。
⼀个简单的⽂档例⼦如下:
{"site":"www.baidu.com", "name":"百度"}
关系总结
RDBMS |
MongoDB |
数据库 |
数据库 |
表 |
集合 |
行 |
文档 |
列 |
字段 |
📝基本操作
库
-
查看所有库
show databases; | show dbs;
注意:
-
admin : 从权限的⻆度来看,这是”root”数据库。要是将⼀个⽤户添加到这个数据库,这个⽤户⾃动 继承所有数据库的权限。⼀些特定的服务器端命令也只能从这个数据库运⾏,⽐如列出所有的数据库 或者关闭服务器。
-
local : 这个数据永远不会被复制,可以⽤来存储限于本地单台服务器的任意集合
-
config : 当Mongo⽤于分⽚设置时,config数据库在内部使⽤,⽤于保存分⽚的相关信息。
-
创建数据库
use 库名
注意: use 代表创建并使⽤,当库中没有数据时默认不显示这个库
-
删除数据库
db.dropDatabase()
默认删除当前选中的库
-
查看当前所在库
db;
集合
-
查看库中所有集合
show collections; | show tables;
-
创建集合
db.createCollection('集合名称', [options])
options可以是如下参数:
字段 |
类 型 |
描述 |
capped |
布尔 |
(可选)如果为 true,则创建固定集合。固定集合是指有着固定⼤⼩的集合,当达到最 ⼤值时,它会⾃动覆盖最早的⽂档。 当该值为 true 时,必须指定 size 参数。 |
size |
数值 |
(可选)为固定集合指定⼀个最⼤值,即字节数。 如果capped 为 true,也需要指定该 字段 。 |
max |
数值 |
(可选)指定固定集合中包含⽂档的最⼤数量。 |
注意:当集合不存在时,向集合中插⼊⽂档也会⾃动创建该集合。
-
删除集合
db.集合名称.drop();
⽂档
参考⽂档: https://docs.mongodb.com/manual/reference/method/
-
插⼊⽂档
-
单条⽂档
db.集合名称.insert({"name":"小芳","age":23,"bir":"2023-1-1"});
-
多条⽂档
db.集合名称.insertMany(
[ <document 1> , <document 2>, ... ],
{
writeConcern: 1,//写⼊策略,默认为 1,即要求确认写操作,0 是不要求。
ordered: true //指定是否按顺序写⼊,默认 true,按顺序写⼊。
}
)
db.集合名称.insert([
{"name":"aa","age":23,"bir":"2022-12-12"},
{"name":"bb","age":25,"bir":"2022-12-12"}
]);
-
脚本⽅式
for(let i=0;i<100;i++){
db.users.insert({"_id":i,"name":"mongo_"+i,"age":23});
}
注意:在 mongodb 中每个⽂档都会有⼀个_id作为唯⼀标识,_id默认会⾃动⽣成如果⼿动指定将使⽤⼿动指定 的值作为_id 的值。
-
查询所有
db.集合名称.find();
-
删除⽂档
db.集合名称.remove(
<query>,
{
justOne: <boolean>,
writeConcern: <document>
}
)
-
参数说明: query : 可选 删除的⽂档的条件。 justOne : 可选 如果设为 true 或 1,则只删除⼀个⽂档,如果不设置该参数,或使⽤默认值 false,则删 除所有匹配条件的⽂档。 writeConcern : 可选 抛出异常的级别。
-
更新⽂档
db.集合名称.update(
<query>,
<update>,
{
upsert: <boolean>,
multi: <boolean>,
writeConcern: <document>
}
);
使用$set
参数说明:
-
query : update的查询条件,类似sql update查询内where后⾯的。
-
update : update的对象和⼀些更新的操作符(如$,$inc…)等,也可以理解为sql update查询内set后⾯的
-
upsert : 可选 ,这个参数的意思是,如果不存在update的记录,是否插⼊objNew,true为插⼊,默认是 false,不插⼊。
-
multi : 可选 ,mongodb 默认是false,只更新找到的第⼀条记录,如果这个参数为true,就把按条件查出来 多条记录全部更新。
-
writeConcern : 可选 ,抛出异常的级别。
- db.集合名称.update({"name":"zhangsan"},{name:"11",bir:new date()})
`这个更新是将符合条件的全部更新成后⾯的⽂档,相当于先删除在更新`
- db.集合名称.update({"name":"xiaohei"},{$set:{name:"mingming"}})
`保留原来数据更新,但是只更新符合条件的第⼀条数据`
- db.集合名称.update({name:”⼩⿊”},{$set:{name:”⼩明”}},{multi:true})
`保留原来数据更新,更新符合条件的所有数据`
- db.集合名称.update({name:”⼩⿊”},{$set:{name:”⼩明”}},{multi:true,upsert:true})
`保留原来数据更新,更新符合条件的所有数据 没有条件符合时插⼊数据
🔍⽂档查询
MongoDB 查询⽂档使⽤ find() ⽅法。find() ⽅法以⾮结构化的⽅式来显示所有⽂档。
语法
db.集合名称.find(query, projection)
-
query :可选,使⽤查询操作符指定查询条件
-
projection :可选,使⽤投影操作符指定返回的键。查询时返回⽂档中所有键值, 只需省略该参数即可 (默认省略)。 (类似于mysql中 select keys…)
如果需要以易读的⽅式来读取数据,可以使⽤ pretty() ⽅法,语法格式如下:
db.集合名称.find().pretty()
注意: pretty() ⽅法以格式化的⽅式来显示所有⽂档。
对⽐语法
如果你熟悉常规的 SQL 数据,通过下表可以更好的理解 MongoDB 的条件语句查询:
AND
db.集合名称.find({key1:value1, key2:value2,...}).pretty()
类似于 WHERE 语句:WHERE key1=value1 AND key2=value2
OR
MongoDB OR 条件语句使⽤了关键字 $or,语法格式如下:
> db.集合名称.find(
{
$or: [
{key1: value1}, {key2:value2}
]
}
).pretty()
类似于 WHERE 语句:WHERE key1=value1 or key2=value2
AND 和 OR 联合
db.集合名称.find({"age": {$gt:50}, $or: [{"name": "张三"},{"name":
"MongoDB"}]}).pretty();
类似SQL语句为:’where age >50 AND (name = ‘张三’ OR name = ‘MongoDB’)’
数组中查询
-- 测试数据
> db.集合名称.insert({ "_id" : 11, "age" : 29, "likes" : [ "看电视", "读书xx", "游戏" ], "name"
: "xx" })
-- 执⾏数组查询
> db.users.find({likes:"看电视"})
-- $size 按照数组⻓度查询
> db.users.find({likes:{$size:3}});
模糊查询
类似 SQL 中为 ‘where name like ‘%name%”
db.users.find({likes:/火/});
注意:在 mongoDB 中使⽤正则表达式可以是实现近似模糊查询功能
排序
> db.集合名称.find().sort({name:1,age:1}),
- 1 升序 -1 降序
类似 SQL 语句为: ‘order by name,age’
分⻚
db.集合名称.find().sort({条件}).skip(start).limit(rows);
类似于 SQL 语句为: ‘limit start,rows’
总条数
> db.集合名称.count();
> db.集合名称.find({"name":"火山"}).count();
类似于 SQL 语句为: ‘select count(id) from ….’
去重
db.集合名称.distinct('字段')
指定返回字段
db.集合名称.find({条件},{name:1,age:1})
- 参数2: 1 返回 0 不返回 `注意:1和0不能同时使⽤`
🔖$type
说明
$type操作符是基于BSON类型来检索集合中匹配的数据类型,并返回结果。 MongoDB 中可以使⽤的类型如下表所示:
使用
db.col.insert({
title: 'PHP 教程',
description: 'PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言。',
by: '火山',
url: 'http://www.runoob.com',
tags: ['php'],
likes: 200
})
db.col.insert({title: 'Java 教程',
description: 'Java 是由Sun Microsystems公司于1995年5月推出的高级程序设计语言。',
by: '火山',
url: 'http://www.runoob.com',
tags: ['java'],
likes: 150
})
db.col.insert({title: 'MongoDB 教程',
description: 'MongoDB 是一个 Nosql 数据库',
by: '火山',
url: 'http://www.runoob.com',
tags: ['mongodb'],
likes: 100
})
db.col.insert({title: 'MongoDB 教程',
description: 1234,
by: '火山',
url: 'http://www.runoob.com',
tags: ['mongodb'],
likes: 100
})
如果想获取 “col” 集合中 description 为 String 的数据,可以使⽤以下命令:
db.col.find({"description" : {$type : 2}}).pretty();
或
db.col.find({"description" : {$type : 'string'}}).pretty();
如果想获取 “col” 集合中 tags 为 Array 的数据,可以使⽤以下命令:
db.col.find({"tags" : {$type : 'array'}}).pretty();
📒索引
https://www.mongodb.com/docs/manual/indexes/
索引通常能够极⼤的提⾼查询的效率,如果没有索引,MongoDB在读取数据时必须扫描集合中的每个⽂件并 选取那些符合查询条件的记录。这种扫描全集合的查询效率是⾮常低的,特别在处理⼤量的数据时,查询可 以要花费⼏⼗秒甚⾄⼏分钟,这对⽹站的性能是⾮常致命的。索引是特殊的数据结构,索引存储在⼀个易于 遍历读取的数据集合中,索引是对数据库表中⼀列或多列的值进⾏排序的⼀种结构。
原理
从根本上说,MongoDB中的索引与其他数据库系统中的索引类似。MongoDB在集合层⾯上定义了索引,并⽀ 持对MongoDB集合中的任何字段或⽂档的⼦字段进⾏索引。
操作
-
创建索引
db.集合名称.createIndex(keys, options)
db.集合名称.createIndex({"title":1,"description":-1})
说明: 语法中 Key 值为你要创建的索引字段,1 为指定按升序创建索引,如果你想按降序来创建索引指定为 -1 即可。
createIndex() 接收可选参数,可选参数列表如下 :
-
查看集合索引
db.集合名称.getIndexes()
-
查看集合索引⼤⼩
db.集合名称.totalIndexSize()
-
删除集合所有索引
db.集合名称.dropIndexes()
-
删除集合指定索引
db.集合名称.dropIndex("索引名称")
复合索引
⼀个索引的值是由多个 key 进⾏维护的索引的称之为复合索引
db.集合名称.createIndex({"title":1,"description":-1})
注意: mongoDB 中复合索引和传统关系型数据库⼀致都是左前缀原则
📄聚合
MongoDB 中聚合(aggregate)主要⽤于处理数据(诸如统计平均值,求和等),并返回计算后的数据结果。有点 类似 SQL 语句中的 count(*)。
使⽤
{
_id: ObjectId(7df78ad8902c)
title: 'MongoDB Overview',
description: 'MongoDB is no sql database',
by_user: 'runoob.com',
url: 'http://www.runoob.com',
tags: ['mongodb', 'database', 'NoSQL'],
likes: 100
},
{
_id: ObjectId(7df78ad8902d)
title: 'NoSQL Overview',
description: 'No sql database is very fast',
by_user: 'runoob.com',
url: 'http://www.runoob.com',
tags: ['mongodb', 'database', 'NoSQL'],
likes: 10
},
{
_id: ObjectId(7df78ad8902e)
title: 'Neo4j Overview',
description: 'Neo4j is no sql database',
by_user: 'Neo4j',
url: 'http://www.neo4j.com',
tags: ['neo4j', 'database', 'NoSQL'],
likes: 750
}
现在我们通过以上集合计算每个作者所写的文章数,使用aggregate()计算结果如下:
db.集合名称.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : 1}}}])
常⻅聚合表达式
📐整合SpringBoot应⽤
环境搭建
引⼊依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
编写配置
# mongodb 没有开启任何安全协议# mongodb(协议)://121.5.167.13(主机):27017(端⼝)/baizhi(库名)spring.data.mongodb.uri=mongodb://121.5.167.13:27017/baizhi# mongodb 存在密码#spring.data.mongodb.host=tx.chenyn.cn#spring.data.mongodb.port=27017#spring.data.mongodb.database=baizhi#spring.data.mongodb.username=root#spring.data.mongodb.password=root
集合操作
创建集合
@Test
public void testCreateCollection(){
mongoTemplate.createCollection("users");//参数: 创建集合名称
}
注意:创建集合不能存在,存在报错
删除集合
@Test
public void testDeleteCollection(){
mongoTemplate.dropCollection("users");
}
相关注解
-
@Document
-
修饰范围: ⽤在类上
-
作⽤: ⽤来映射这个类的⼀个对象为 mongo 中⼀条⽂档数据
-
属性:( value 、collection )⽤来指定操作的集合名称
-
@Id
-
修饰范围: ⽤在成员变量、⽅法上
-
作⽤: ⽤来将成员变量的值映射为⽂档的_id 的值
-
@Field
-
修饰范围: ⽤在成员变量、⽅法上
-
作⽤: ⽤来将成员变量以及值映射为⽂档中⼀个key、value对
-
属性: ( name,value )⽤来指定在⽂档中 key 的名称,默认为成员变量名
-
@Transient
-
修饰范围: ⽤在成员变量、⽅法上
-
作⽤ : ⽤来指定改成员变量,不参与⽂档的序列化
⽂档操作
-
添加
@Test
public void testSaveOrUpdate(){
User user = new User(1, "小鸭子", 2000.1, new Date());
User userDB = mongoTemplate.save(user);//返回保存的对象 insert or save
List<User> users = Arrays.asList(
new User(3, "大鸭子", 2000.1, new Date()), new User(4, "中鸭子", 2000.1, new Date())
);
mongoTemplate.insert(users,User.class); // 批量插入
}
insert: 插⼊重复数据时: insert 报 DuplicateKeyException 提示主键重复; save 对已存在的数据 进⾏更新。 save: 批处理操作时: insert 可以⼀次性插⼊整个数据,效率较⾼; save 需遍历整个数据,⼀次插 ⼊或更新,效率较低。
-
查询
-
Criteria
-
常⻅查询
@Test
public void testFind(){
// 查询所有
List<User> users = mongoTemplate.findAll(User.class);
// 根据id查询
User user = mongoTemplate.findById(5, User.class);
//查询所有
mongoTemplate.findAll(User.class);
mongoTemplate.find(new Query(),User.class);
//等值查询
mongoTemplate.find(Query.query(Criteria.where("name").is("小黄鸭")), User.class);
// < > <= >= 查询
mongoTemplate.find(Query.query(Criteria.where("age").lt(100)), User.class);
// and 查询
mongoTemplate.find(Query.query(Criteria.where("name").is("小黄鸭").and("age").is(20)), User.class);
// or 查询
Criteria criteria = new Criteria();
criteria.orOperator(
Criteria.where("name").is("小黄鸭"),
Criteria.where("name").is("大黄鸭")
);
mongoTemplate.find(Query.query(criteria), User.class);
//and or
Criteria criteria1 = new Criteria()
.and("age").is(23)
.orOperator(
Criteria.where("name").is("小黄鸭"),
Criteria.where("name").is("大黄鸭"));
mongoTemplate.find(Query.query(criteria1), User.class);
// 排序
Query querySort = new Query();
querySort.with(Sort.by(Sort.Order.desc("age")));
mongoTemplate.find(querySort, User.class);
//skip limit 分⻚
Query queryPage = new Query();
queryPage.with(Sort.by(Sort.Order.desc("age")))//desc 降序 asc 升序
.skip(0) //起始条数
.limit(2); //每⻚显示记录数
mongoTemplate.find(queryPage, User.class);
//count 总条数
mongoTemplate.count(new Query(), User.class);
//distinct 去重
//参数 1:查询条件 参数 2: 去重字段 参数 3: 操作集合 参数 4: 返回类型
mongoTemplate.findDistinct(new Query(), "name", User.class, String.class);
//使⽤ json 字符串⽅式查询
Query query = new BasicQuery(
"{$or:[{name:'小黄鸭'},{name:'大黄鸭'}]}",
"{name:0}");
mongoTemplate.find(query, User.class);
}
-
更新
@Test
public void testUpdate1(){
//1.更新条件
Query query = Query.query(Criteria.where("age").is(23));
//2.更新内容
Update update = new Update();
update.set("name","小黄鸭");
//单条更新
mongoTemplate.updateFirst(query, update, User.class);
//多条更新
mongoTemplate.updateMulti(query, update, User.class);
//更新插⼊
mongoTemplate.upsert(query,update,User.class);
//返回值均为 updateResult
//System.out.println("匹配条数:" + updateResult.getMatchedCount());
//System.out.println("修改条数:" + updateResult.getModifiedCount());
//System.out.println("插⼊id_:" + updateResult.getUpsertedId());
}
-
删除
@Test
public void testDelete(){
//删除所有
mongoTemplate.remove(new Query(),User.class);
//条件删除
mongoTemplate.remove(
Query.query(Criteria.where("name").is("编程不良⼈")),
User.class
);
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/154444.html