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的基本使用及对接多数据源的更多相关文章

  1. Superset连接Impala数据源

    公司最近在superset上面做二次开发,目前对接了mysql和oracle数据源,对这两个源的SQL操作查询做了完善和兼容.目前有新的需求就是要对接大数据部门的HBASE和HIVE数据源,由于sup ...

  2. JSON数据从MongoDB迁移到MaxCompute最佳实践

    数据及账号准备 首先您需要将数据上传至您的MongoDB数据库.本例中使用阿里云的云数据库 MongoDB 版,网络类型为VPC(需申请公网地址,否则无法与DataWorks默认资源组互通),测试数据 ...

  3. spark sql使用sequoiadb作为数据源

    目前没有实现,理一下思路,有3中途径: 1:spark core可以使用sequoiadb最为数据源,那么是否spark sql可以直接操作sequoiadb. 2: spark sql支持Hive, ...

  4. spring mongodb 复制集配置(实现读写分离)

    注:mongodb当前版本是3.4.3   spring连接mongodb复制集的字符串格式: mongodb://[username:password@]host1[:port1][,host2[: ...

  5. SQL Server 2019 深度解读:微软数据平台的野望

    本文为笔者在InfoQ首发的原创文章,主要利用周末时间陆续写成,也算近期用心之作.现转载回自己的公众号,请大家多多指教. 11 月 4 日,微软正式发布了其新一代数据库产品 SQL Server 20 ...

  6. Apache Kyuubi 在 T3 出行的深度实践

    支撑了80%的离线作业,日作业量在1W+ 大多数场景比 Hive 性能提升了3-6倍 多租户.并发的场景更加高效稳定 T3出行是一家基于车联网驱动的智慧出行平台,拥有海量且丰富的数据源.因为车联网数据 ...

  7. Tapdata肖贝贝:实时数据引擎系列(三) - 流处理引擎对比

      摘要:本文将选取市面上一些流计算框架包括 Flink .Spark .Hazelcast,从场景需求出发,在核心功能.资源与性能.用户体验.框架完整性.维护性等方面展开分析和测评,剖析实时数据框架 ...

  8. 教你如何解决T+0的问题

    摘要:T+0查询是指实时数据查询,数据查询统计时将涉及到最新产生的数据. 本文分享自华为云社区<大数据解决方案:解决T+0问题>,作者: 小虚竹 . T+0问题 T+0查询是指实时数据查询 ...

  9. jmeter接口测试

    一.Jmeter简介 Jmeter是apache公司基于java开发的一款开源压力测试工具,体积小,功能全,使用方便,不像loadrunner那样体积大,是一个比较轻量级的测试工具,使用起来非常的简单 ...

随机推荐

  1. 附件携马之CS免杀shellcode过国内主流杀软

    0x01 写在前面 其实去年已经写过类似的文章,但是久没用了,难免有些生疏.所谓温故而知新,因此再详细的记录一下,一方面可以给各位看官做个分享,另一方面等到用时也不至于出现临阵磨枪的尴尬场面. 0x0 ...

  2. SQL 练习18

    按各科成绩进行排序,并显示排名, Score 重复时保留名次空缺 SELECT t.cid,t.sid,t.score ,COUNT(t1.score)+1 as 排名 from sc as t LE ...

  3. noip模拟10

    被打回原形了emmmmm 贴张图吧,展示一下根本不行的水平 考试经过 上来浏览一遍T1到T3,读懂题之后发现都不是很可做 T1上了想到了前缀和,往矩阵快速幂想了一下觉得不可做,半小时之后还是只会\(n ...

  4. wpf 绘图

  5. LeetCode42. 接雨水(java)

    42.接雨水 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水. 上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种 ...

  6. Java学习之 多态 Polymorphism

    转自:http://www.cnblogs.com/mengdd/archive/2012/12/25/2832288.html 多态的概念 多态==晚绑定. 不要把函数重载理解为多态. 因为多态是一 ...

  7. ecshop文件架构

    /*ECShop 2.5.1 的结构图及各文件相应功能介绍ECShop2.5.1_Beta upload 的目录┣ activity.php 活动列表┣ affiche.php 广告处理文件┣ aff ...

  8. Redis实现主从复制以及sentinel的配置

    redis 是一个高性能的 key-value 数据库. redis 的出现,很大程度补偿了 memcached 这类 keyvalue 存储的不足,在部分场合可以对关系数据库起到很 好的补充作用.它 ...

  9. 微信小程序 image 组件 src 请求不能设置 header 的问题

    只能先 wx.downloadFile 得到 tempFilePath,然后设置 src = tempFilePath

  10. vue 打开新窗口进行打印

    父文件 let { href } = this.$router.resolve({ path: ' 自己配置本地路由,不需要动态路由 ', query: 个人建议传一整个对象 }) window.op ...