非关系型数据库(1)---MongoDB
MongoDB是一个基于文档的NoSQL数据库,它使用JSON-like的BSON格式来存储数据。MongoDB的设计旨在提供高性能、高可用性和易于扩展的特点,特别适合处理大量数据和高并发的数据访问需求。在MongoDB中,对数据库本身的操作包括创建数据库、切换数据库、删除数据库以及查看数据库信息等。如果数据库不存在,则会创建一个新的数据库。命令可以删除当前数据库。命令可以查看当前数据库的统计信息
目录
1.MongoDB
MongoDB是一个基于文档的NoSQL数据库,它使用JSON-like的BSON格式来存储数据。MongoDB的设计旨在提供高性能、高可用性和易于扩展的特点,特别适合处理大量数据和高并发的数据访问需求。
1.MongoDB的特点
- 文档存储:数据存储在类似JSON的文档中,每个文档都可以有不同的字段和结构。
- 动态模式:不需要预先定义数据结构,可以根据需要动态添加字段。
- 高可用性:支持自动故障转移和复制集,确保数据的持久性和可用性。
- 水平扩展:通过分片技术,可以在多个服务器上分布数据,实现水平扩展。
- 丰富的查询语言:支持丰富的查询操作,包括聚合、索引、文本搜索等。
2.MongoDB的应用场景
- 大数据处理:适合处理大规模数据集,如日志分析、实时数据监控等。
- 实时应用:适用于需要快速读写操作的应用,如社交网络、实时聊天应用等。
- 内容管理:适合存储和检索非结构化数据,如博客、文章、媒体内容等。
- 物联网(IoT):处理来自大量设备的传感器数据。
3.MongoDB与MySQL的比较
- 数据模型:MySQL使用关系型数据模型,而MongoDB使用文档型数据模型。
- 查询语言:MySQL使用SQL,而MongoDB使用自己的查询语言。
- 扩展性:MongoDB支持水平扩展,而MySQL更适合垂直扩展。
- 事务处理:MySQL支持复杂的事务处理,而MongoDB在4.0版本后开始支持多文档事务。
2.数据库操作
MongoDB对数据库本身的操作
在MongoDB中,对数据库本身的操作包括创建数据库、切换数据库、删除数据库以及查看数据库信息等。以下是一些常用的命令行操作:
1. 创建数据库
在MongoDB中,数据库是通过使用use命令切换到不存在的数据库来创建的。当你第一次存储数据时,数据库和集合会被自动创建。
use newDatabaseName
2. 切换数据库
使用use命令可以切换到已经存在的数据库。如果数据库不存在,则会创建一个新的数据库。
use existingDatabaseName
3. 查看所有数据库
使用show dbs命令可以查看当前MongoDB实例中的所有数据库。
show dbs
4. 查看当前数据库
使用db命令可以查看当前操作的数据库。
db
5. 删除数据库
使用db.dropDatabase()命令可以删除当前数据库。这个操作会删除数据库中的所有集合、文档和索引。
db.dropDatabase()
6. 查看数据库统计信息
使用db.stats()命令可以查看当前数据库的统计信息,例如数据大小、索引大小、文档数量等。
db.stats()
7. 备份数据库
使用mongodump工具可以备份MongoDB数据库。以下是一个基本的备份命令:
mongodump --db databaseName --out backupDirectory
8. 恢复数据库
使用mongorestore工具可以恢复MongoDB数据库。以下是一个基本的恢复命令:
mongorestore --db databaseName backupDirectory
9. 创建用户和授权
在MongoDB中,你可以创建用户并对数据库进行授权。以下是一些基本的用户和权限管理命令:
use admin
db.createUser({
user: "username",
pwd: "password",
roles: [{ role: "readWrite", db: "databaseName" }]
})
10. 删除用户
使用db.dropUser()命令可以删除数据库中的用户。
db.dropUser("username")
11. 查看用户列表
使用show users命令可以查看当前数据库中的用户列表。
show users
3.集合和文档操作
1. 创建集合
使用db.createCollection()命令可以显式创建一个集合。
db.createCollection("collectionName")
2. 删除集合
使用db.collection.drop()命令可以删除一个集合及其所有文档。
db.collectionName.drop()
3. 重命名集合
使用db.collection.renameCollection()命令可以重命名一个集合。
db.collectionName.renameCollection("newCollectionName")
4. 查看所有集合
使用show collections或db.getCollectionNames()命令可以查看当前数据库中的所有集合。
show collections
或
db.getCollectionNames()
5. 插入文档
使用db.collection.insert()命令可以在集合中插入一个或多个文档。
db.collectionName.insert({key: "value"})
6. 查询文档
使用db.collection.find()命令可以查询集合中的文档。
db.collectionName.find({key: "value"})
7. 更新文档
使用db.collection.update()命令可以更新集合中的文档。
db.collectionName.update({key: "value"}, {$set: {key: "newValue"}})
8. 删除文档
使用db.collection.remove()命令可以删除集合中的文档。
db.collectionName.remove({key: "value"})
9. 创建索引
使用db.collection.createIndex()命令可以为集合创建索引。
db.collectionName.createIndex({key: 1})
10. 删除索引
使用db.collection.dropIndex()命令可以删除集合中的索引。
db.collectionName.dropIndex({key: 1})
11. 查看索引
使用db.collection.getIndexes()命令可以查看集合中的所有索引。
db.collectionName.getIndexes()
12. 计数文档
使用db.collection.count()命令可以计算集合中的文档数量。
db.collectionName.count()
13. distinct操作
使用db.collection.distinct()命令可以返回集合中指定键的不同值。
db.collectionName.distinct("key")
14. aggregate聚合
使用db.collection.aggregate()命令可以进行复杂的聚合操作。
db.collectionName.aggregate([{$match: {key: "value"}}, {$group: {_id: "$key", count: {$sum: 1}} }])
15. findAndModify
使用db.collection.findAndModify()命令可以原子性地查找并修改文档。
db.collectionName.findAndModify({
query: {key: "value"},
update: {$set: {key: "newValue"}},
new: true
})
16. bulkWrite
使用db.collection.bulkWrite()命令可以执行批量写入操作,包括插入、更新和删除。
db.collectionName.bulkWrite([
{insertOne: {document: {key: "value"}}},
{updateOne: {filter: {key: "value"}, update: {$set: {key: "newValue"}}, upsert: true}},
{deleteOne: {filter: {key: "value"}}}
])
4.查询操作
-
基本查询操作
- 查找所有文档:使用
find()方法可以查找集合中的所有文档。例如,db.collection.find()。 - 查找特定文档:通过在
find()方法中指定查询条件,可以查找满足条件的特定文档。例如,db.collection.find({ field: "value" })。 - 返回特定字段:可以使用投影(projection)来指定返回的字段。例如,
db.collection.find({ field: "value" }, { field1: 1, field2: 1 })。
- 查找所有文档:使用
-
条件查询操作
- 比较操作符:如
$eq(等于)、$ne(不等于)、$gt(大于)等。例如,db.collection.find({ field: {$gt: 10 } })。 - 逻辑操作符:包括
$and、$or、$not和$nor。例如,db.collection.find({ $or: [{ field1: "value1" }, { field2: "value2" }] })。 - 元素操作符:如
$exists和$type,用于查询包含特定字段或类型的文档。例如,db.collection.find({ field: { $exists: true } })。 - 数组操作符:如
$in、$nin、$all,用于查询数组字段。例如,db.collection.find({ arrayField: {$in: [1, 2, 3] } })。 - 正则表达式:用于模糊查询。例如,
db.collection.find({ field: { $regex: "pattern" } })。
- 比较操作符:如
-
聚合查询操作
- 基本聚合管道:聚合管道由多个阶段组成,每个阶段对数据进行处理。例如,
db.collection.aggregate([ { $match: { field: "value" } }, {$group: { _id: "$field", total: {$sum: "$anotherField" } } } ])。 - 常用聚合操作符:如
$match、$group、$project、$sort、$limit、$skip等。 - 聚合表达式:如
$sum、$avg、$min、$max等,用于在聚合阶段进行计算。
- 基本聚合管道:聚合管道由多个阶段组成,每个阶段对数据进行处理。例如,
-
高级查询技巧
- 使用索引:合理使用索引可以显著提高查询性能。
- 查询优化:使用
explain()方法分析查询性能。 - 分页查询:使用
limit()和skip()方法进行分页查询。 - 地理空间查询:使用地理空间索引和操作符进行地理位置查询
5.SpringBoot集成MongoDB
-
保存操作:
save(T entity):保存单个实体。saveAll(Iterable<T> entities):保存多个实体。
-
查找操作:
findById(ID id):根据ID查找实体。findById(ID id, Class<T> type):根据ID查找实体,并指定返回类型。findAll():查找所有实体。findAll(Iterable<ID> ids):根据ID列表查找多个实体。findAll(Sort sort):查找所有实体并排序。findAll(Example<T> example):根据示例查找实体。findAll(Example<T> example, Sort sort):根据示例查找实体并排序。
-
删除操作:
deleteById(ID id):根据ID删除实体。delete(T entity):删除单个实体。deleteAll(Iterable<? extends T> entities):删除多个实体。deleteAll():删除所有实体。
-
更新操作:
save(T entity):保存或更新实体(如果实体已存在,则更新;如果不存在,则保存)。
-
计数操作:
count():计算所有实体的数量。count(Example<T> example):根据示例计算实体的数量。
-
存在性检查:
existsById(ID id):检查ID对应的实体是否存在。
-
自定义查询:
- 可以通过在
MongoRepository接口中定义方法并使用MongoDB的查询注解(如@Query)来执行自定义查询。
- 可以通过在
-
分页和排序:
findAll(Pageable pageable):分页查询所有实体。findAll(Sort sort):排序查询所有实体。
-
聚合操作:
- 使用
Aggregation类来执行复杂的聚合操作,如分组、过滤、转换等。
- 使用
-
地理空间操作:
- 如果实体包含地理空间数据,可以使用地理空间查询方法,如
near、within等。
- 如果实体包含地理空间数据,可以使用地理空间查询方法,如
-
事务管理:
- 使用
@Transactional注解来管理事务。
- 使用
-
索引管理:
- 使用
@Indexed注解来定义索引。
- 使用
6. 主从复制(Replica Set)
MongoDB 使用 副本集(Replica Set)来实现数据的高可用性,副本集是由多个 MongoDB 实例组成的集群,包含一个主节点(Primary)和多个从节点(Secondary)。主节点处理所有的写操作,而从节点复制主节点的数据。
设置副本集
-
启动多个 MongoDB 实例,每个实例使用不同的端口:
mongod --port 27017 --dbpath /data/db1 --replSet "rs0" mongod --port 27018 --dbpath /data/db2 --replSet "rs0" mongod --port 27019 --dbpath /data/db3 --replSet "rs0" -
连接到其中一个实例并初始化副本集:
mongo --port 27017在 MongoDB shell 中运行:
rs.initiate() -
添加成员到副本集:
rs.add("localhost:27018") rs.add("localhost:27019") -
检查副本集状态:
rs.status()
主从复制的工作方式
- 主节点:接受所有的写操作,所有的客户端请求写入都发送到主节点。
- 从节点:通过 oplog(操作日志)从主节点复制数据。当主节点宕机时,副本集中的一个从节点会被自动提升为新的主节点(自动故障转移)。
配置读取和写入策略
-
读偏好(Read Preference):可以配置客户端从哪一节点读取数据:
db.getMongo().setReadPref("secondary") // 从从节点读取 db.getMongo().setReadPref("primary") // 从主节点读取 -
写关注(Write Concern):设置写操作的确认策略,确保数据写入的可靠性:
db.collection.insertOne({ ... }, { writeConcern: { w: "majority" } })
7. 分片(Sharding)
分片是 MongoDB 实现水平扩展的机制,通过将数据分布在多个节点上来扩展数据库的存储和计算能力。每个分片在逻辑上是一个独立的数据库,MongoDB 会自动管理数据的分布。
设置分片
-
启用分片:首先,启动一个 配置服务器(Config Server)来存储分片元数据,然后启动 路由进程(Mongos)。
启动配置服务器:
mongod --configsvr --port 27019 --dbpath /data/config启动路由进程:
mongos --configdb localhost:27019 -
添加分片服务器:启动分片服务器并添加到集群中:
mongod --shardsvr --port 27020 --dbpath /data/shard1 mongod --shardsvr --port 27021 --dbpath /data/shard2 -
连接到路由进程:
mongo --host localhost --port 27017 -
添加分片:
复制代码
sh.addShard("localhost:27020") sh.addShard("localhost:27021")
配置分片键
选择一个字段作为 分片键,该字段用于决定文档存储在哪个分片上。分片键必须是查询中经常使用的字段。
- 选择分片键并启用分片:
sh.enableSharding("mydb") sh.shardCollection("mydb.mycollection", { "field": 1 })
分片的工作方式
- 数据库中的数据根据 分片键 分布到不同的分片上。
- 查询会通过路由进程(Mongos)转发到适当的分片。
- 写入操作也根据分片键将数据分布到相应的分片。
查看分片状态
- 查看分片的分布情况:
sh.status()
8. 事务(Transactions)
MongoDB 在 4.0 版本开始支持多文档事务,允许跨多个文档和集合执行原子操作。
开启事务
事务通过 MongoDB 的会话(Session)机制来实现。
-
开始事务:
const session = db.getMongo().startSession() session.startTransaction() -
执行多文档操作:
const collection1 = session.getDatabase("test").getCollection("col1") const collection2 = session.getDatabase("test").getCollection("col2") collection1.insertOne({ _id: 1, value: "A" }) collection2.insertOne({ _id: 1, value: "B" }) -
提交事务:
session.commitTransaction() -
回滚事务:
session.abortTransaction() -
结束会话:
session.endSession()
事务的特性
- 原子性:事务中的所有操作要么全部成功,要么全部回滚。
- 一致性:事务执行前后数据库保持一致。
- 隔离性:事务之间不会相互干扰。
- 持久性:事务提交后,所有修改都会持久化。
9. 全文搜索(Full-text Search)
MongoDB 4.2 及以后版本支持 全文搜索,可以通过 MongoDB 的 text 索引实现。
创建 text 索引
-
创建全文索引:
db.collection.createIndex({ field: "text" }) -
查询全文搜索:
db.collection.find({ $text: { $search: "keyword" } }) -
指定搜索选项:
db.collection.find({ $text: { $search: "keyword", $caseSensitive: false, $diacriticSensitive: false } }) -
排序根据文本得分:
db.collection.find({ $text: { $search: "keyword" } }).sort({ score: { $meta: "textScore" } })
10. 备份和恢复
备份
- 使用
mongodump工具备份整个数据库或特定集合:mongodump --host localhost --port 27017 --out /path/to/backup
恢复
- 使用
mongorestore工具恢复数据:mongorestore --host localhost --port 27017 /path/to/backup
11. 数据库用户和权限管理
MongoDB 支持细粒度的用户权限控制,可以为用户分配不同的角色来控制他们对数据库的访问。
创建用户
-
创建用户并赋予角色:
db.createUser({ user: "username", pwd: "password", roles: [{ role: "readWrite", db: "mydb" }] }) -
查看用户:
db.getUsers() -
删除用户:
db.dropUser("username")
更多推荐
所有评论(0)