概述

MongoDB是一个基于分布式文件存储文档型数据库,是专为可扩展性高性能高可用性而设计的数据库,是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。且在4.0版本开始支持ACID事务特性中文文档

主要特点:

  • MongoDB 是一个面向文档存储的数据库,操作起来比较简单和容易。
  • 你可以在MongoDB记录中设置任何属性的索引 (如:FirstName=”Sameer”,Address=”8 Gandhi Road”)来实现更快的排序。
  • 你可以通过本地或者网络创建数据镜像,这使得MongoDB有更强的扩展性。
  • 如果负载的增加(需要更多的存储空间和更强的处理能力) ,它可以分布在计算机网络中的其他节点上这就是所谓的分片。
  • Mongo支持丰富的查询表达式。查询指令使用JSON形式的标记,可轻易查询文档中内嵌的对象及数组。
  • MongoDb 使用update()命令可以实现替换完成的文档(数据)或者一些指定的数据字段 。
  • Mongodb中的Map/reduce主要是用来对数据进行批量处理和聚合操作。
  • Map和Reduce。Map函数调用emit(key,value)遍历集合中所有的记录,将key与value传给Reduce函数进行处理。
  • Map函数和Reduce函数是使用Javascript编写的,并可以通过db.runCommand或mapreduce命令来执行MapReduce操作。
  • GridFS是MongoDB中的一个内置功能,可以用于存放大量小文件。
  • MongoDB允许在服务端执行脚本,可以用Javascript编写某个函数,直接在服务端执行,也可以把函数的定义存储在服务端,下次直接调用即可。
  • MongoDB支持各种编程语言:RUBY,PYTHON,JAVA,C++,PHP,C#等多种语言。

准备工作

安装

Docker安装(推荐)

  • 使用wsl2配合docker,体验极佳
  • 拉取镜像 docker pull mongo
  • 启动容器(快速开始)
    1
    docker run -d --name mongo -p 27017:27017 mongo
    需要登录验证
    1
    docker run -d -p 27017:27017 --name mongodb -e MONGO_INITDB_ROOT_USERNAME=root -e MONGO_INITDB_ROOT_PASSWORD=root --auth mongo

Windows中安装

https://www.runoob.com/mongodb/mongodb-window-install.html

Linux中安装

https://www.runoob.com/mongodb/mongodb-linux-install.html

客户端工具

链接格式:mongodb:// 账号:密码@主机:端口[,账号:密码@主机:端口]/数据库名?参数

  • mongodb://localhost
  • mongodb://admin:admin@localhost/mycollection
  • mongodb://localhost,localhost:27018,localhost:27019
  • 连接 replica set 三台服务器, 写入操作应用在主服务器 并且分布查询到从服务器。
    mongodb://host1,host2,host3/?slaveOk=true
  • 直接连接第一个服务器,无论是replica set一部分或者主服务器或者从服务器。
    mongodb://host1,host2,host3/?connect=direct;slaveOk=true
    当你的连接服务器有优先级,还需要列出所有服务器,你可以使用上述连接方式。
  • 安全模式连接
    mongodb://localhost/?safe=true
  • 以安全模式连接到replica set,并且等待至少两个复制服务器成功写入,超时时间设置为2秒。
    mongodb://host1,host2,host3/?safe=true;w=2;wtimeoutMS=2000

非常牛逼的Navicat Premium 15(推荐)

Navicat Premium 是一套数据库开发工具,让你从单一应用程序中同时连接 MySQL、MariaDB、MongoDB、SQL Server、Oracle、PostgreSQL 和 SQLite 数据库。它与 Amazon RDS、Amazon Aurora、Amazon Redshift、Microsoft Azure、Oracle Cloud、MongoDB Atlas、阿里云、腾讯云和华为云等云数据库兼容。你可以快速轻松地创建、管理和维护数据库。
官网下载 破解教程

Windows Shell(mongo.exe)

前往官网下载mongodb-windows.msi,安装时只勾选client即可

Robo 3T

官网下载

体系结构

MongoDB中通过数据库(database)、集合(collection)、文档(document)的方式来管理数据

flowchart LR subgraph DB["数据库(database)"] subgraph C1["集合(collection)"] D1["文档(document)"] D2["文档(document)"] end subgraph C2["集合(collection)"] D3["文档(document)"] D4["文档(document)"] end end

MongoDB与关系数据库的一些概念对比:

SQL术语/概念 MongoDB术语/概念 解释/说明
database database 数据库
table collection 数据库表/集合
row document 数据记录行/文档
column field 数据字段/域
index index 索引
table joins 表连接(MongoDB不支持)
primary key primary key 主键,MongoDB自动在每个集合中添加_id的主键

BSON数据类型

BSON是一种二进制序列化格式,用于在MongoDB中存储文档和进行远程过程调用。BSON规范位于bsonspec.org
每种BSON类型都具有整数和字符串标识符,如下表所示:

类型 对应数字 别名 备注
Double (64位 双精度浮点型) 1 double 默认数值类型
String (字符串) 2 string UTF-8字符串
Object (对象/内嵌文档) 3 object
Array (数组) 4 array
Binary data (二进制数据) 5 binData
Undefined (未定义) 6 undefined 不推荐使用。
ObjectId (对象编号) 7 objectId 用于文档唯一_id的生成,长度为12个字节
Boolean (布尔型) 8 bool true和false
Date (日期) 9 date
Null (空值) 10 null 表示空值或者不存在的字段
Regular Expression (正则表达式) 11 regex 查询时,使用正则表达式作为限定条件
DBPointer 12 dbPointer 不推荐使用。
JavaScript 13 javascript
Symbol 14 symbol 不推荐使用。
JavaScript (带范围) 15 javascriptWithScope
32-bit integer (32位整数) 16 int 使用 NumberInt(“20”) 来表示
Timestamp (时间戳) 17 timestamp
64-bit integer (64位整数) 18 long 使用 NumberLong(“114514114514”) 来表示
Decimal128 (128位 浮点型) 19 decimal 3.4版的新功能。
Min key (最小键) -1 minKey
Max key (最大键) 127 maxKey

常用命令

https://www.runoob.com/mongodb/mongodb-create-database.html

Java操作MongoDB

MongoDB Driver

基本

添加MongoDB Driver依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public void test(){
//创建mongodb 客户端
MongoClient client = new MongoClient("localhost", 27017);
//采用连接字符串创建
//MongoClient client = new MongoClient(new MongoClientURI("mongodb://root:root@localhost:27017"));//连接数据库
MongoDatabase db = client.getDatabase("mydb");
// 连接collection
MongoCollection<Document> collection = db.getCollection("mycol");
//查询第一个文档
Document doc = collection.find().first();
//得到文件内容 json串
String json = doc.toJson();
System.out.println(json);
//关闭客户端
client.close();
}

添加

1
2
3
4
5
6
7
8
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("name","john");
map.put("age",20);
map.put("job","eat");
Document document = new Document(map);
collection.insertOne(document);
//关闭客户端
client.close();

批量添加

1
2
3
4
5
6
List<DBObject> objs = new ArrayList<DBObject>();
objs.add(new BasicDBObject("name","john1").append("age", 20).append("job", "eat"));
objs.add(new BasicDBObject("name","john2").append("age", 20).append("job", "sleep"));
collection.insert(objs);
//关闭客户端
client.close();

条件查询

1
2
3
4
5
6
7
8
9
10
//构建查询条件
BasicDBObject stu = new BasicDBObject("name","zhangfei");
//执行查询
FindIterable<Document> documents = collection.find(stu);
//输出
for (Document document : documents) {
//...
}
//关闭客户端
client.close();

MongoTemplate

条件查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
@Autowired
private MongoTemplate mongo;

@Override
public PageResult<Information> list(Information searchParams, int pageNum, int pageSize) {
Query query = new Query();
//根据标题模糊查询
if (StringUtil.isNotEmpty(searchParams.getTitle()))
query.addCriteria(Criteria.where("title").regex(searchParams.getTitle()));
//根据发布时间降序排序
if (searchParams.getSortType() == 1)
query.with(Sort.by(Sort.Order.desc("publishTime")));
//根据发布时间区间模糊查询
if (searchParams.getPublishTimeStart() != null && searchParams.getPublishTimeEnd() != null)
query.addCriteria(Criteria.where("publishTime").gte(searchParams.getPublishTimeStart()).lte(searchParams.getPublishTimeEnd()));
else {
if (searchParams.getPublishTimeStart() != null)
query.addCriteria(Criteria.where("publishTime").gte(searchParams.getPublishTimeStart()));
if (searchParams.getPublishTimeEnd() != null)
query.addCriteria(Criteria.where("publishTime").lte(searchParams.getPublishTimeEnd()));
}
//根据所属板块精确查询
if (searchParams.getAppBoardId() != null)
query.addCriteria(Criteria.where("appBoardId").is(searchParams.getAppBoardId()));
//分页结果
long total = mongo.count(query, Information.class);
query.with(PageRequest.of(pageNum - 1, pageSize));
List<Information> list = mongo.find(query, Information.class);
return new PageResult<>(total, list);
}

SpringMongoDBData

添加Spring Boot Starter Data MongoDB依赖

  • 定义实体类
    Student.java
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    @Data //lombok注解
    @Document("student") //标记集合
    public class Student {
    @Id //标记主键
    @Field("_id") //字段别名
    private int id;
    private String name;
    private int age;
    //@Transient 可以忽略此属性 不持久化
    private String hobby;
    }
  • 定义dao层接口,继承 MongoRepository<实体类,主键类型>
    StudentDao.java
    1
    2
    public interface StudentDao extends MongoRepository<Student,Integer> {
    }
  • service层直接按JPA规范调用即可
    文件名
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    @Service
    public class StudentService {
    @Autowired
    private StudentDao studentDao;
    public List<Student> listAll() {
    return studentDao.findAll();
    }
    public void add(Student student) {
    studentDao.insert(student);
    }
    public void update(Student student) {
    studentDao.save(student);
    }
    public void delete(int id) {
    studentDao.deleteById(id);
    }
    public PageResult<Student> listByPage(int pageNum, int pageSize) {
    Page<Student> page = studentDao.findAll(PageRequest.of(pageNum - 1, pageSize));
    return new PageResult<>(page.getTotalElements(),page.getContent());
    }
    }