MongoDB是一个基于分布式文件存储的数据库,由C++语言编写,旨在为WEB应用提供可扩展的高性能数据存储解决方案。

MongoDB是介于关系数据库非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。它支持的数据结构非常松散,是类似json的bson格式,因此可以存储比较复杂的数据类型。

Mongo最大的特点是它支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引

应用场景

MongoDB相较于传统的关系型数据库,可应对“三高“需求

  • High performance:对数据库高并发读写的需求
  • Huge Storage:对海量数据的高效率存储和访问的需求
  • High Scalability && High Availability:对数据库的高可扩展性和高可用性的需求

什么时候选择MongoDB

  • 新应用,需求会变,数据模型无法确定,想快速迭代开发
  • 应用需要2000-3000以上的读写QPS(更高也可以)
  • 应用需要TB甚至PB级别数据存储
  • 应用要求存储的数据不丢失
  • 应用需要99.999%高可用

体系结构

SQL术语/概念 MongoDB术语/概念 说明
database database 数据库
table collection 数据库表/集合
row document 数据记录行/文档
column field 数据字段/域
index index 索引
primary key primary key 主键

数据类型

MongoDB的最小存储单位是文档(document)对象。数据在MongoDB中以BSON(Binary-JSON)文档的格式存储在磁盘上。

BSON(Binary Serialized Document Format)是一种类json的一种二进制形式的存储格式,简称Binary JSON。BSON和JSON一样,支持内嵌的文档对象和数组对象,但是BSON有JSON没有的一些数据类型,如Date和BinData类型。

BSON采用了类似于C语言结构体的名称、对表示方法,支持内嵌的文档对象和数组对象,具有轻量性、可遍历性、高效性的三个特点,可以有效描述非结构化数据和结构化数据。这种格式的优点是灵活性高,但它的缺点是空间利用率不是很理想。

Bson中,除了基本的JSON类型:string,integer,boolean,double,null,array和object,mongo还使用了特殊的数据类型。这些类型包括date,object id,binary data,regular expression和code。

MongoDB优点

  1. 高性能

​ MongoDB提供高性能的数据持久性。特别是对嵌入式数据模型的支持减少了数据库系统上I/O活动。索引支持更快的查询,并且可以包含来自嵌入式文档和数组的键。

  1. 高可用性
    MongoDB的复制工具称为副本集(replica set),它可提供自动故障转移和数据冗余

  2. 高扩展性
    MongoDB提供了水平可扩展性作为其核心功能的一部分。分片将数据分布在一组集群的机器上。(海量数据存储,服务能力水平扩展)

    从3.4开始,MoηgoDB支持基于片键创建数据区域。在一个平衡的集群中, MongoDB将一个区域所覆盖的读写只定向到该区域内的那些片。

  3. 丰富的查询支持
    MongoDB支持丰富的査询语言,支持读和写操作(CRUD),比如数据聚合、文本搜索和地理空间查询等

常用命令

需要用到的时候可以查阅MongoDB官方文档,在此列举常用命令

基本命令

mongosh:打开一个连接到本地实例的MongoShell。所有其他命令都需要在mongosh中执行

show databases\show dbs:显示当前MongoDB实例中的所有数据库

use <dbname>:切换到dbname数据库

cls: 清屏

show collections: 显示数据库中的所有集合

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

exit: 退出

创建、插入

insertOne:在集合中插入一个新的文档,如果集合存在,那么直接插入数据。如果集合不存在,那么会隐式创建。

  • db.test.insertOne({name: "Jack", age: 18}):向test数据库中插入一条数据

insertMany:批量插入文档

快速插入

由于mongodb底层使用JS引擎实现的,所以支持部分Js语法。因此可以写for循环

for (var i=1; i<=10; i++) { db.c2.insertOne({uanme: "a"+i, age: i}) }

删除

delectOne:删除满足条件的第一个文档

delectMany:删除满足条件的所有文档

更新

updateOne:更新满足条件的第一个文档

updateMany:更新满足条件的所有文档

replaceone:替换满足条件的第一个文档

save:通过传入的文档替换已有文档或插入一个新的文档

$set:只更新文档中$set指定的字段

  • db.test.update({name:"Jack"},{$set:{uname:"Candy"}}):把jack改成Candy

$inc:用于递增/递减文档中指定字段值的操作符

$rename:更新某个字段的名称

$unset:删除一个字段

$push:将值加入一个数组中,不会判断是否有重复的值

$pull:将值从一个数组中移除

$addToSet:将值加入一个数组中,如果数组中有重复的值则不会加入

查找

find:查询所有文档

find(<filterObject>):查询所有满足参数对象<filterObject>中指定过滤条件的数据

  • db.test.find({age: 18}):查询所有年龄为18岁的文档

db.find(<filterObject>, <selectObject>):查询所有满足参数对象<filterObject>中指定过滤条件的数据,并且只返回或者不返回<selectObject>中指定的字段

  • db.test.find({}, {name:1}):只看name列
  • db.test.find({}, {name:0}):除了name列都看

findOne:与find用法相同,但是只返回1条

countDocuments:返回满足条件的记录的数量

sort:使用给定的字段按照升序或降序排序

  • db.test.find().sort({age:1}):按照年龄升序排序(传入-1是降序排序)

limit:限定只返回给定数量的文档

  • db.test.find().limit(1):只返回一条数据

skip:从头开始跳过给定数值的文档

  • db.test.find().limit(x).skip(y*x):实现翻页效果,一页x个内容,翻y页

聚合函数

$sum:计算总和

$avg:计算平均值

$min:计算最小值

$max:计算最大值

$first:获取第一个文档数据

$last:获取最后一个文档数据

过滤条件

$eq:等于

$ne:不等于

$gt\$get:大于\大于等于

  • db.c1.find({age:{$gt:5}}):查询age大于5的数据

$lt\$lte:小于\小于等于

$in:值在指定列表中就返回文档

  • db.c2.find({age:{$in:[5,8,10]}}):查询年龄是5,8,10的数据

$nin:值不在指定列表中就返回文档

$and:检查复数条件是否均为真,可以理解为“并且”

  • db.test.find({$and:[{age:{$gte:10}}, {age:{$lte:20}}}]}):返回年龄在10-20岁之间的文档

$or:检查复试条件是否有一个为真,可以理解为“或者”

$not:逻辑区取反

$exists:检查一个字段是否存在

$expr:在不同的字段中作比较

Java中操作MongoDB

首先需要导入mongodb驱动包

<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version></version>
</dependency>

创建链接对象

MongoClient mongoclient= new MongoClient("127.0.0.1", 27017);

查看数据库

//获取库对象,参数为库名
MongoDatabase db = mongoclient.getDatabase("test");
//获取当前库对象的所有集合名的迭代器
MongoIterable<String> list = db.getlistCollectionNames();
for(String str:list){
System.out.println(str);//获取所有表
}
//获取集合对象,参数为集合名
MongoCollention<Document> collection = db.getCollection("student");

对数据库进行增删改查

新增数据

//获取集合对象
MongoCollection<Document> collection = db.getCollection("test");
//新增时创建一个Docuement对象,以键值对的形式传入内容
Document document = new Document();
document.put("name", "张三");
document.put("age", 21);
document.put("sex", "男");
//添加一条数据,没有返回值
collection.insertOne(document);
//新增多条数据,传入一个document集合
collection.insertMany(null);

Filter类

删除,修改,查询时传入的筛选条件,比如Bson eq = Filters.eq("name","张三");

常用方法
方法 说明
Filters.eq() 等值
Filters.gt() 大于指定值(gte大于等于)
Filters.lt() 小于指定值(lte小于等于)
Filters.ne() 不等于指定
Filters.nin() 不等于数组中的值
Filters.and() 传入多个Bson对象,and连接
Filters.regex() 模糊查询
Filters.exists() 存在改字段

删除数据

//条件
Bson eq = Filters.eq("name","张三");
//删除一条符合的
DeleteResult deleteOne = collection.deleteOne(eq);
//删除 所有符合条件的
DeleteResult deleteMany = collection.deleteMany(eq);

修改的返回值内容

AcknowledgedDeleteResult{deletedCount=0}

deletedCount:被删除的文档数

修改数据

//修改条件
Bson eq = Filters.eq("name","张三");
//修改匹配到的第一条
UpdateResult updateOne = collection.updateOne(
eq, new Document("$set",new Document("age",50)));
//修改匹配的多条
collection.updateMany(eq, null);

修改的返回值内容

AcknowledgedUpdateResult{matchedCount=0, modifiedCount=0, upsertedId=null}

matchedCount:代表匹配到的文档数

modifiedCount:代表被修改的文档数

upsertedId:代表修改的文档id(主键)

查询数据

//无条件全查
FindIterable<Document> find = collection.find();
//带条件查询
Bson eq = Filters.regex("name", "张");
FindIterable<Document> find = collection.find(eq);

查询的结果集映射,这种解析方式我们必须知道文档中的各个字段名

//查询
FindIterable<Document> find = collection.find();
//创建一个实体类集合准备接收结果
List<Student> slist = new ArrayList<Student>();
//获取结果集迭代器对象
MongoCursor<Document> iterator = find.iterator();
while(iterator.hasNext()) {
Student s = new Student();
Document next = iterator.next();
s.setSname(next.getString("name"));
s.setSex(next.getString("sex"));
s.setAge(next.getInteger("age"));
//将结果添加至实体类集合
slist.add(s);
}

释放资源

mongoclient.close();