Mongodb的基本使用及对接多数据源
mongodb介绍
MongoDB(来自于英文单词“Humongous”,中文含义为“庞大”)是可以应用于各种规模的企业、各个行业以及各类应用程序的开源数据库。基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。MongoDB是一个高性能,开源,无模式的文档型数据库,是当前NoSql数据库中比较热门的一种。
MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。
MongoDB是一个文档数据库。这里对比RDBMS来介绍Mongodb。
传统的关系数据库一般由数据库(database)、表(table)、记录(record)三个层次概念组成,MongoDB是由数据库(database)、集合(collection)、文档对象(document)三个层次组成。MongoDB的collection对应关系型数据库里的表,但是集合中没有列、行和关系概念
1、基本概念
1.1、数据库:
在Mongodb中,db表示数据库,对应RDBMS的数据库。
'show dbs'
可以查看所有数据库
'use 数据库名称'
表示使用指定数据库
1.2、集合:
集合Collections对应 RDBMS的表
'show collections'
可以查看当前db下所有集合
1.3、文档:
文档对应RDBMS的表中的数据
db.'集合名称'.find();
表示查询当前集合下所有文档数据。其中文档是以BSON进行存储,BSON是一种二进制序列化格式,用于在MongoDB中存储文档和进行远程过程调用。参考BSON介绍
2、特性
2.1、高性能:
- 对嵌入式数据模型的支持减少了数据库系统上的I / O操作
- 索引支持更快的查询,并且可以包含来自嵌入式文档和数组的键
2.2、丰富的查询语言:
- MongoDB支持丰富的查询语言以支持读写操作(CRUD)
- 数据聚合
- 文本搜索和地理空间查询
2.3、高可用:
- MongoDB的复制工具(称为副本集)提供 自动故障转移 和 数据冗余。副本集是一组维护相同数据集合的 mongod实例,提供了冗余和提高了数据可用性。
2.4、水平拓展:
- MongoDB提供水平可伸缩性作为其核心 功能的一部分:数据分片切割将数据分布在一个集群的机器上。
- 从3.4开始,MongoDB支持基于分片键创建数据区域。在平衡群集中,MongoDB仅将区域覆盖的读写定向到区域内的那些分片。
2.5、支持多种存储引擎:
- WiredTiger存储引擎(包括对静态加密的支持 )
- 内存存储引擎
- PS: MongoDB提供可插拔的存储引擎API,允许第三方为MongoDB开发存储引擎
3、mongodb基本命令使用
使用mongodb自带的mongodb Shell来学习mongodb提供的基本CRUD操作
3.1、进入mongodb安装路劲的bin目录
mongo --host 127.0.0.1 --port 27017 // 使用命令连接mongodb并使用mongodb Shell
show dbs //查询所有数据库
use mytest //使用指定的数据库
db.myCollection01.insertOne( {x : 1} ); //创建文档{x : 1} 如果没有数据库和集合,那么会默认创建集合和数据库,并插入文档到集合中
MongoDB中的所有写操作都是单个文档级别的原子操作。 有关MongoDB和原子性的更多信息,请参见原子性
3.2、新增操作
db.inventory.insertOne(
{ item: "canvas", qty: 100, tags: ["cotton"], size: { h: 28, w: 35.5, uom: "cm" } }
) //插入文档到集合inventory中,如果集合不存在,那么会默认创建集合
db.inventory.insertMany([
{ item: "journal", qty: 25, size: { h: 14, w: 21, uom: "cm" }, status: "A" },
{ item: "notebook", qty: 50, size: { h: 8.5, w: 11, uom: "in" }, status: "A" },
{ item: "paper", qty: 100, size: { h: 8.5, w: 11, uom: "in" }, status: "D" },
{ item: "planner", qty: 75, size: { h: 22.85, w: 30, uom: "cm" }, status: "D" },
{ item: "postcard", qty: 45, size: { h: 10, w: 15.25, uom: "cm" }, status: "A" }
]); //插入多条文档
3.3、查询操作
db.inventory.find( {} ) // SELECT * FROM inventory
db.inventory.find( { status: "D" } ) // SELECT * FROM inventory WHERE status = "D"
db.inventory.find( { status: { $in: [ "A", "D" ] } } ) // SELECT * FROM inventory WHERE status in ("A", "D")
db.inventory.find( { status: "A", qty: { $lt: 30 } } ) // SELECT * FROM inventory WHERE status = "A" AND qty < 30
db.inventory.find( { $or: [ { status: "A" }, { qty: { $lt: 30 } } ] } ) // SELECT * FROM inventory WHERE status = "A" OR qty < 30
db.inventory.find( {
status: "A",
$or: [ { qty: { $lt: 30 } }, { item: /^p/ } ]
} ) // SELECT * FROM inventory WHERE status = "A" AND ( qty < 30 OR item LIKE "p%")
3.4、删除操作
db.inventory.deleteMany({}) // 从inventory收集中删除所有文档
db.inventory.deleteMany({ status : "A" }) // 从状态字段等于“ A”的inventory集合中删除所有文档
db.inventory.deleteOne( { status: "D" } ) // 删除状态为“ D”的第一个文档
即使从集合中删除所有文档,删除操作也不会删除索引。
3.5、修改操作
先使用插入多条数据插入示例数据,在示例数据的基础上进行更新操作
db.inventory.insertMany( [
{ item: "canvas", qty: 100, size: { h: 28, w: 35.5, uom: "cm" }, status: "A" },
{ item: "journal", qty: 25, size: { h: 14, w: 21, uom: "cm" }, status: "A" },
{ item: "mat", qty: 85, size: { h: 27.9, w: 35.5, uom: "cm" }, status: "A" },
{ item: "mousepad", qty: 25, size: { h: 19, w: 22.85, uom: "cm" }, status: "P" },
{ item: "notebook", qty: 50, size: { h: 8.5, w: 11, uom: "in" }, status: "P" },
{ item: "paper", qty: 100, size: { h: 8.5, w: 11, uom: "in" }, status: "D" },
{ item: "planner", qty: 75, size: { h: 22.85, w: 30, uom: "cm" }, status: "D" },
{ item: "postcard", qty: 45, size: { h: 10, w: 15.25, uom: "cm" }, status: "A" },
{ item: "sketchbook", qty: 80, size: { h: 14, w: 21, uom: "cm" }, status: "A" },
{ item: "sketch pad", qty: 95, size: { h: 22.85, w: 30.5, uom: "cm" }, status: "A" }
] ); //插入多条示例文档
db.inventory.updateOne(
{ item: "paper" },
{
$set: { "size.uom": "cm", status: "P" },
$currentDate: { lastModified: true }
}
)
// 使用$set 运算符将size.uom字段的值更新为“ cm”,将状态字段的值更新为“ P”,使用$currentDate运算符将lastModified字段的值更新为当前日期。 如果lastModified字段不存在,则$currentDate将创建该字段
要替换_id字段以外的文档的全部内容,请将一个全新的文档作为第二个参数传递给db.collection.replaceOne()。
在替换文档中,由于_id字段是不可变的,因此可以省略_id字段。如果确实包含_id字段,则它必须与当前值具有相同的值
db.inventory.replaceOne(
{ item: "paper" },
{ item: "paper", instock: [ { warehouse: "A", qty: 60 }, { warehouse: "B", qty: 40 } ] }
)//替换了inventory集合中的第一个文件,其中项为"paper":
文档设置后,您将无法更新_id字段的值,也无法将现有文档替换为具有不同_id字段值的替换文档
除以下情况外,MongoDB会在执行写操作后保留文档字段的顺序:
- _id字段始终是文档中的第一个字段。
- 包含字段名称renaming 的更新可能导致文档中字段的重新排序
如果updateOne(), updateMany(), or replaceOne() 包含upsert:true,并且没有文档与指定的过滤器匹配,则该操作将创建一个新文档并将其插入。 如果存在匹配的文档,则该操作将修改或替换一个或多个匹配的文档。
4、java操作mongodb
Spring Data的MongoRepository和MongoTemplate。
4.1、MongoRepository依次实现了PagingAndSortingRepository、CrudRepository、Spring Data的Repository
- Repository: 仅仅是一个标识,表明任何继承它的均为仓库接口类
- CrudRepository: 继承 Repository,实现了一组 CRUD 相关的方法
- PagingAndSortingRepository: 继承 CrudRepository,实现了一组分页排序相关的方法
- MongoRepository: 继承 PagingAndSortingRepository,实现一组 mongodb规范相关的方法 //自定义的 XxxxRepository 需要继承 MongoRepository,这样的 XxxxRepository 接口就具备了通用的数据访问控制层的能力(CURD的操作功能)
MongoRepository的缺点是不够灵活,MongoTemplate正好可以弥补不足
4.2、MongoTemplate采用了模板方法设计模式,封装了代码调用获取链接执行语句等操作。
- MongoTemplate实现了interface MongoOperations。
- MongoDB documents和domain classes之间的映射关系是通过实现了MongoConverter这个interface的类来实现的。
- MongoTemplate提供了非常多的操作MongoDB的方法。 它是线程安全的,可以在多线程的情况下使用。
- MongoTemplate实现了MongoOperations接口, 此接口定义了众多的操作方法如"find", "findAndModify", "findOne", "insert", "remove", "save", "update" and "updateMulti"等。
- MongoTemplate转换domain object为DBObject,缺省转换类为MongoMappingConverter,并提供了Query, Criteria, and Update等流式API
MongoTemplate的类结构如下:其中有两个重要的操作类
Criteria类:封装所有的语句,以方法的形式查询。
Query类:将语句进行封装或者添加排序之类的操作。
从上面类结构可以知道使用 Query 构造方法,传入一个Criteria类,可以构建一个简单的过滤器去进行CRUD。
下面介绍使用MongoTemplate进行简单的crud
//yml配置
spring:
data:
mongodb:
uri: mongodb://localhost:27017/mytest
//测试代码
@RunWith(SpringRunner.class)
@SpringBootTest
public class MongodbUtil {
@Autowired
private MongoTemplate mongoTemplate;
//
// @Autowired
// private PersonRepository personRepository;
/**
* insert document
*
* {
* "name" : "cgg",
* "info": {
* "age" : 18
* }
* }
*/
@Test
public void testInsert() {
Map<String, Object> data = Maps.newHashMap();
Map<String, Object> info = Maps.newHashMap();
data.put("name", "cgg");
info.put("age" , 18);
data.put("info", info);
mongoTemplate.insert(data, "inventory");
System.out.println(mongoTemplate.findAll(Map.class, "inventory"));
}
/**
* select * from inventory where status in ('A')
*/
@Test
public void testQuery() {
Query query = new Query();
query.addCriteria(Criteria.where("status").in("A"));
mongoTemplate.executeQuery(query, "inventory", System.out::println);
}
/**
* update inventory set qty = 55 where status in ('A')
*/
@Test
public void testUpdate() {
Query query = new Query();
query.addCriteria(Criteria.where("status").in("A"));
Update update = new Update();
update.set("qty", 55);
mongoTemplate.updateMulti(query, update, "inventory");
System.out.println(mongoTemplate.findAll(Map.class, "inventory"));
}
/**
* delete from inventory where name = 'cgg'
*/
@Test
public void testDelete() {
Query query = new Query();
query.addCriteria(Criteria.where("name").in("cgg"));
mongoTemplate.remove(query, "inventory");
testQuery();
}
}
5、mongodb客户端
mongodb客户端有很多,这里推荐大家使用Robo,支持查看各种语言的查询语句、结果集转换,筛选查询,查看查询计划等等
Robo下载地址Robo studio
6、mongodb对接多数据源
Springboot项目整合mongodb多数据源配置
#yml配置
spring:
data:
mongodb:
one:
uri: mongodb://localhost:27017/mytest
two:
uri: mongodb://localhost:27018/mytest
/**
* mongodb 多数据源属性配置类
*
* @author cgg
* @since 2021/07/21
* @version 1.0
*/
@Configuration
public class MongoConfiguration {
@Bean(name = "oneMongoProperties")
@Primary
@ConfigurationProperties(prefix = "spring.data.mongodb.one")
public MongoProperties masterMongoProperties() {
return new MongoProperties();
}
@Bean(name = "twoMongoProperties")
@ConfigurationProperties(prefix = "spring.data.mongodb.two")
public MongoProperties twoMongoProperties() {
return new MongoProperties();
}
}
/**
* mongodb://localhost:27017/mytest 数据源配置类 完成MongoTemplate的注入
*
* @author cgg
* @since 2021/07/21
* @version 1.0
*/
@Configuration
@EnableMongoRepositories(mongoTemplateRef = "oneMongo")
public class OneMongoTemplateConf {
private final MongoProperties mongoProperties;
public OneMongoTemplateConf(@Qualifier("oneMongoProperties") MongoProperties mongoProperties) {
this.mongoProperties = mongoProperties;
}
@Bean(name = "oneMongo")
@Primary
public MongoTemplate mongoTemplate() {
return new MongoTemplate(mongoDatabaseFactory(mongoProperties));
}
@Bean(name = "oneMongoFactory")
@Primary
public MongoDatabaseFactory mongoDatabaseFactory(MongoProperties mongoProperties) {
return new SimpleMongoClientDatabaseFactory(mongoProperties.getUri());
}
}
/**
*
* mongodb://localhost:27018/mytest 数据源配置类 完成MongoTemplate的注入
*
* @author cgg
* @since 2021/07/21
* @version 1.0
*/
@Configuration
@EnableMongoRepositories(mongoTemplateRef = "twoMongo")
public class TwoMongoTemplateConf {
private final MongoProperties mongoProperties;
public TwoMongoTemplateConf(@Qualifier("twoMongoProperties") MongoProperties mongoProperties) {
this.mongoProperties = mongoProperties;
}
@Bean(name = "twoMongo")
public MongoTemplate mongoTemplate() {
return new MongoTemplate(mongoDatabaseFactory(mongoProperties));
}
@Bean(name = "twoMongoFactory")
public MongoDatabaseFactory mongoDatabaseFactory(MongoProperties mongoProperties) {
return new SimpleMongoClientDatabaseFactory(mongoProperties.getUri());
}
}
/**
* mongodb 多数据源测试
*
* @author cgg
* @since 2021/07/21
* @version 1.0
*/
@RunWith(SpringRunner.class)
@SpringBootTest
public class MongoTest {
@Autowired
@Qualifier("oneMongo")
private MongoTemplate oneMongoTemplate;
@Autowired
@Qualifier("twoMongo")
private MongoTemplate twoMongoTemplate;
/**
* 向 localhost:27017/mytest插入数据
*/
@Test
public void testOneMongoInsert() {
Map<String, Object> data = Maps.newHashMap();
Map<String, Object> info = Maps.newHashMap();
data.put("name", "cgg");
data.put("attr", "one");
info.put("age" , 18);
data.put("info", info);
oneMongoTemplate.insert(data, "inventory_27017");
System.out.println(oneMongoTemplate.findAll(Map.class, "inventory_27017"));
}
/**
* 向 localhost:27018/mytest插入数据
*/
@Test
public void testTwoMongoInsert() {
Map<String, Object> data = Maps.newHashMap();
Map<String, Object> info = Maps.newHashMap();
data.put("name", "cgg");
data.put("attr", "two");
info.put("age" , 18);
data.put("info", info);
twoMongoTemplate.insert(data, "inventory_27018");
System.out.println(twoMongoTemplate.findAll(Map.class, "inventory_27018"));
}
}
多数据源配置,测试结果展示
7、MongoDB CRUD概念
上面介绍了mongodb的入门使用,关于mongodb,还有数据模型、事务、索引、聚合、安全、复制、分片、管理、存储等等。下一篇将着重介绍Mongodb的更多使用和特性。
Mongodb的基本使用及对接多数据源的更多相关文章
- Superset连接Impala数据源
公司最近在superset上面做二次开发,目前对接了mysql和oracle数据源,对这两个源的SQL操作查询做了完善和兼容.目前有新的需求就是要对接大数据部门的HBASE和HIVE数据源,由于sup ...
- JSON数据从MongoDB迁移到MaxCompute最佳实践
数据及账号准备 首先您需要将数据上传至您的MongoDB数据库.本例中使用阿里云的云数据库 MongoDB 版,网络类型为VPC(需申请公网地址,否则无法与DataWorks默认资源组互通),测试数据 ...
- spark sql使用sequoiadb作为数据源
目前没有实现,理一下思路,有3中途径: 1:spark core可以使用sequoiadb最为数据源,那么是否spark sql可以直接操作sequoiadb. 2: spark sql支持Hive, ...
- spring mongodb 复制集配置(实现读写分离)
注:mongodb当前版本是3.4.3 spring连接mongodb复制集的字符串格式: mongodb://[username:password@]host1[:port1][,host2[: ...
- SQL Server 2019 深度解读:微软数据平台的野望
本文为笔者在InfoQ首发的原创文章,主要利用周末时间陆续写成,也算近期用心之作.现转载回自己的公众号,请大家多多指教. 11 月 4 日,微软正式发布了其新一代数据库产品 SQL Server 20 ...
- Apache Kyuubi 在 T3 出行的深度实践
支撑了80%的离线作业,日作业量在1W+ 大多数场景比 Hive 性能提升了3-6倍 多租户.并发的场景更加高效稳定 T3出行是一家基于车联网驱动的智慧出行平台,拥有海量且丰富的数据源.因为车联网数据 ...
- Tapdata肖贝贝:实时数据引擎系列(三) - 流处理引擎对比
摘要:本文将选取市面上一些流计算框架包括 Flink .Spark .Hazelcast,从场景需求出发,在核心功能.资源与性能.用户体验.框架完整性.维护性等方面展开分析和测评,剖析实时数据框架 ...
- 教你如何解决T+0的问题
摘要:T+0查询是指实时数据查询,数据查询统计时将涉及到最新产生的数据. 本文分享自华为云社区<大数据解决方案:解决T+0问题>,作者: 小虚竹 . T+0问题 T+0查询是指实时数据查询 ...
- jmeter接口测试
一.Jmeter简介 Jmeter是apache公司基于java开发的一款开源压力测试工具,体积小,功能全,使用方便,不像loadrunner那样体积大,是一个比较轻量级的测试工具,使用起来非常的简单 ...
随机推荐
- Spring全家桶--单数据源的配置
前言 spring数据源的配置网络上有很多例子,这里我也来介绍一下单数据源配置的例子,基于SpringBoot的方式和原生的Spring的方式. 一.生成项目骨架(SpringBoot),运行一个简单 ...
- SQL 练习41
编写一个 SQL 查询,获取 Employee 表中第二高的薪水(Salary) 例如上述 Employee 表,SQL查询应该返回 200 作为第二高的薪水.如果不存在第二高的薪水,那么查询应返回 ...
- SSM自学笔记(四)
8.面向切面编程AOP 1.Spring 的 AOP 简介 1.1 什么是 AOP AOP 为 Aspect Oriented Programming 的缩写,意思为面向切面编程,是通过预编译方式和运 ...
- 让div占据父元素剩下的所有位置
场景模拟: 现在有一个父容器,里面有俩个div,左边的要给一个固定的200px的宽度,父容器剩下的宽度都归右边的div该怎么完成?HTML代码: <div class="wrap&qu ...
- vue项目梳理
vue实例 vue2.x中创建vue实例,挂载到dom节点 点击查详情 <div id="vue_det"> <h1>site : {{site}}< ...
- excel快捷键如下:
ALT+ 空格键,然后按下 X ALT+ 空格键,然后按下 R 首先打开表格,在A1对角用鼠标左键单击,界面会全部选中,然后调整字体大小框里的数字,回车,表格就变大了. 同时按Alt和E,再按L ...
- rasa form的中断形式 自然机器语言学习 人工智能
Forms形式 最常见的对话模式之一是从用户那里收集一些信息以便做某事(预订餐厅.调用 API.搜索数据库等).这也称为**槽填充**. 用法# 要在 Rasa Open Source 中使用表单,您 ...
- 【XSS】XSS修炼之独孤九剑
题目地址 xcao.vip/test 题目作者给出的解题思路 http://xcao.vip/test/xss/XSS修炼之独孤九剑.pdf 独孤九剑-第一式 题目 过滤了等号 =.小括号 (),要求 ...
- 【CSS】按钮
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 源码编译安装nginx及设置开机启动项
1.上传nginx文档:解压到/data目录下,并安装依赖包tar xf nginx-1.20.1.tar.gz -C /data/cd /data/nginx-1.20.1/ && ...