# MongoDB
MongoDB
MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统。
在高负载的情况下,添加更多的节点,可以保证服务器性能。
MongoDB 旨在为WEB应用提供可扩展的高性能数据存储解决方案。
MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组成。MongoDB 文档类似于 JSON 对象。字段值可以包含其他文档,数组及文档数组。
# 服务安装
进入 官网 ,选择适合自己的安装包,并复制下载链接
下载并解压安装包
# 下载 wget https://downloads.mongodb.com/linux/mongodb-linux-x86_64-enterprise-rhel70-5.0.5.tgz # 解压 tar -xzvf mongodb-linux-x86_64-enterprise-rhel70-5.0.5.tgz # 进入解压后的文件夹 cd mongodb-linux-x86_64-enterprise-rhel70-5.0.5 # 创建data目录和log目录 mkdir data mkdir log touch log/mongodb.log # 启动服务 (默认在27017端口启动) bin/mongod --dbpath ./data --logpath ./log/mongodb.log --bind_ip_all --fork # 客户端连接 bin/mongo
其它
若服务启动有以下报错, 说明是依赖包未安装,安装以下即可
# bin/mongod: error while loading shared libraries: libnetsnmpmibs.so.31: cannot open shared object file: No such file or director yum install net-snmp
# 概念解析
MongoDB术语/概念 | SQL术语/概念 | 解释/说明 |
---|---|---|
database | database | 数据库 |
collection | table | 数据库表/集合 |
document | row | 数据记录行/文档 |
field | column | 数据字段/域 |
index (普通索引、联合索引、唯一索引) | index | 索引 |
/ | table joins | 表连接 |
primary key | primary key | 主键,MongoDB自动将_id字段设置为主键 |
# 数据库
和关系型数据库一样,一个mongodb中可以创建多个数据库,每个数据库可以有自己的集合和权限,数据存储于
执行“show dbs" 命令可以展示所有数据库列表, 第一列显示数据库名称,第二列显示对应数据库所占用的存储空间
MongoDB Enterprise > show dbs;
admin 0.000GB
config 0.000GB
local 0.000GB
lowan-iot 0.001GB
test 0.000GB
其中 "admin"、"config"、"local" 为 mongodb 默认创建的数据库
- admin : 从权限的角度来看,这是"root"数据库。要是将一个用户添加到这个数据库,这个用户自动继承所有数据库的权限。一些特定的服务器端命令也只能从这个数据库运行,比如列出所有的数据库或者关闭服务器。
- local: 这个数据永远不会被复制,可以用来存储限于本地单台服务器的任意集合
- config: 当Mongo用于分片设置时,config数据库在内部使用,用于保存分片的相关信息。
执行 "db" 命令可以显示当前数据库对象
MongoDB Enterprise > db
test
执行 "use" 命令可以切换到一个指定的数据库
MongoDB Enterprise > use lowan-iot
switched to db lowan-iot
MongoDB Enterprise >
# 文档
文档是一组键值(key-value)对(即 BSON)。MongoDB 的文档不需要设置相同的字段,并且相同的字段不需要相同的数据类型,这与关系型数据库有很大的区别,也是 MongoDB 非常突出的特点。
# 集合
集合就是 MongoDB 文档组,类似于 RDBMS (关系数据库管理系统:Relational Database Management System)中的表格。
集合存在于数据库中,集合没有固定的结构,这意味着你在对集合可以插入不同格式和类型的数据,但通常情况下我们插入集合的数据都会有一定的关联性。
比如,我们可以将以下不同数据结构的文档插入到集合中:
{"site":"www.baidu.com"}
{"site":"www.google.com","name":"Google"}
{"site":"www.runoob.com","name":"菜鸟教程","num":5}
# MongoDB 数据类型
数据类型 | 描述 |
---|---|
String | 字符串。存储数据常用的数据类型。在 MongoDB 中,UTF-8 编码的字符串才是合法的。 |
Integer | 整型数值。用于存储数值。根据你所采用的服务器,可分为 32 位或 64 位。 |
Boolean | 布尔值。用于存储布尔值(真/假)。 |
Double | 双精度浮点值。用于存储浮点值。 |
Min/Max keys | 将一个值与 BSON(二进制的 JSON)元素的最低值和最高值相对比。 |
Array | 用于将数组或列表或多个值存储为一个键。 |
Timestamp | 时间戳。记录文档修改或添加的具体时间。 |
Object | 用于内嵌文档。 |
Null | 用于创建空值。 |
Symbol | 符号。该数据类型基本上等同于字符串类型,但不同的是,它一般用于采用特殊符号类型的语言。 |
Date | 日期时间。用 UNIX 时间格式来存储当前日期或时间。你可以指定自己的日期时间:创建 Date 对象,传入年月日信息。 |
Object ID | 对象 ID。用于创建文档的 ID。 |
Binary Data | 二进制数据。用于存储二进制数据。 |
Code | 代码类型。用于在文档中存储 JavaScript 代码。 |
Regular expression | 正则表达式类型。用于存储正则表达式。 |
# SpringBoot 连接 MongoDB
# 环境配置
在项目的pom文件中引入依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency>
在配置文件中配置连接信息
spring: data: mongodb: host: 192.168.20.195:27017 database: lowan-iot auto-index-creation: true
在需要与mongodb数据库交互的地方注入
MongoTemplate
@Resource private MongoTemplate mongoTemplate;
# 创建集合
在项目启动成功后提前创建所有需要的集合
// 创建实体,在实体的类上加入注解 Document @Data @Document("object_model_log") @CompoundIndex(def = "{'timestamp':1, 'deviceId':1}") public class ObjectModelDataLog { private String deviceId; private String messageType; private Long timestamp; } // 调用方法 MongoTemplate#createCollection(java.lang.Class<T>) mongoTemplate.createCollection(ObjectModelDataLog.class); // 或者调用重载方法 MongoTemplate#createCollection(java.lang.String) mongoTemplate.createCollection("object_model_log");
动态创建集合
MongoDB属于NoSQL的范畴,无schema模式设计,即使未提前创建集合,也可以在插入数据的时候根据Document动态创建集合
# 插入文档
插入文档需要有两个参数,第一个是集合的名称,第二个是需要插入的数据
public void handle(List<Message> messages) {
List<JSONObject> dataList = new ArrayList<>();
for (Message message : messages) {
if (message.getData().isEmpty()) {
continue;
}
JSONObject data = new JSONObject(message.getData());
data.put("deviceId", message.getDeviceId());
data.put("timestamp", message.getTimestamp());
data.put("messageType", message.getMessageType());
dataList.add(data);
}
mongoTemplate.insert(dataList, ObjectModelDataLog.class);
}
# 查询文档
查询文档需要有三个参数,第一个为集合的名称,第二个为查询条件,第三个为查询结果的接收实体类型
// 第一个参数,集合名称
String collectionName = "object_model_log";
// 第二个参数,查询条件,对字段值进行过滤
Criteria criteria = Criteria.where("deviceId").is(query.getDeviceId());
criteria.and("messageType").is(query.getMessageType());
Query mongoQuery = new Query(criteria);
// 设置分页查询参数--若不需要分页,可忽略以下参数
mongoQuery.skip(((long) query.getOffset()))
.limit(query.getPageSize())
.with(Sort.by(Sort.Order.desc(DevLogKeys.TIMESTAMP)));
// 执行查询,并获取结果
List<JSONObject> list = mongoTemplate.find(mongoQuery, JSONObject.class, collectionName);
# 更新文档
更新文档也需要三个参数,第一个为集合的名称,第二个为查询条件,第三个为更新的字段值
// 集合名称
String collectionName = "object_model_log";
// 查询参数
Query query = new Query();
query.addCriteria(Criteria.where("deviceId").is(message.getDeviceId()));
// 需要更新的值
Update update = new Update();
update.set("timestamp", message.getTimestamp());
JSONObject data = message.getData();
for (Map.Entry<String, Object> entry : data.entrySet()) {
if (entry.getValue() != null) {
update.set(entry.getKey(), entry.getValue());
}
}
// 执行更新操作
mongoTemplate.update(query, update, collectionName);
# 删除文档
// 集合名称
String collectionName = "object_model_log";
// 查询参数
Query query = new Query();
query.addCriteria(Criteria.where("deviceId").is(message.getDeviceId()));
// 执行删除
mongoTemplate.remove(query, collectionName);