完全掌握MongoDB
MongoDB介绍
什么是MongoDB?
MongoDB是一个面向文档的数据库,它以类似JSON格式的BSON(Binary JSON)文档来存储数据。每个文档可以具有不同的结构,这使得MongoDB非常灵活且适用于存储各种类型的数据,而无需事先定义数据模式。这种非常自由的数据模型使得MongoDB在开发过程中更加灵活,容易进行迭代和快速原型设计。
与传统SQL数据库的比较
与传统的关系型SQL数据库相比,MongoDB具有以下几个显著的区别:
- 数据模型:MongoDB是面向文档的数据库,数据以文档的形式存储,每个文档可以包含嵌套的子文档和数组。而传统SQL数据库使用表格来存储数据,需要定义表格结构和关系。
- 架构设计:在MongoDB中,设计数据库结构相对简单,不需要像传统SQL数据库那样进行规范化和拆分。这样可以减少复杂的JOIN操作,并提高查询性能。
- 数据查询:MongoDB的查询语言非常强大,支持复杂的查询和聚合操作,同时具有灵活的索引和查询优化。而在传统SQL数据库中,查询需要使用SQL语言,可能需要多个JOIN操作。
- 扩展性:MongoDB天生支持横向扩展,也就是说可以通过添加更多的服务器来分布数据和负载。这使得MongoDB在大规模应用和处理海量数据时表现出色。
NoSQL数据库的优势
NoSQL数据库的优势主要体现在以下几个方面:
- 灵活性:NoSQL数据库如MongoDB允许存储非结构化或半结构化数据,因此更适合处理复杂的、变化频繁的数据。
- 可扩展性:NoSQL数据库天生支持横向扩展,可以轻松应对大规模的数据和高并发访问。
- 高性能:由于不涉及复杂的JOIN操作和规范化,NoSQL数据库通常具有更快的查询性能。
- 易于开发:NoSQL数据库的文档型数据模型使得开发人员可以更自由地设计和修改数据模式,不需要事先定义表格结构,从而提高开发效率。
然而,需要注意的是,NoSQL数据库也有其局限性。例如,由于数据模式不是事先定义的,数据一致性和完整性可能需要在应用程序层面进行处理。因此,在选择数据库时,需要根据具体的应用场景和需求来权衡NoSQL数据库的优势和限制。
Mongodb 对比 Mysql
概念 | MongoDB | MySQL |
---|---|---|
数据库 | 面向文档的数据库,数据以JSON格式的BSON文档进行存储 | 关系型数据库,数据以表格形式存储,每个表有行和列 |
集合/表 | 集合是一组文档的容器,类似于表 | 表是存储数据的基本单位,由行和列组成 |
文档/行 | 文档是基本数据单元,类似于JSON对象 | 行是表中的一条记录,包含各个属性的值 |
字段/列 | 文档中的键值对,表示文档的属性 | 表中的列,用于存储特定类型的数据 |
主键 | 每个文档有唯一的"_id"字段用于标识文档 | 表中可以有主键,用于标识表中的每一行 |
事务 | 支持事务操作(较新版本) | 支持传统事务操作 |
数据模型 | 灵活的文档数据模型,适合半结构化或非结构化数据 | 严格的表格数据模型,适合结构化数据 |
查询语言 | 使用类似于JSON的查询语言 | 使用SQL进行查询操作 |
安装和配置MongoDB
Windows
Mongodb下载地址
选择msi下载(这个是下一步下一步那个)
下载图形化界面
安装完成
Linux
下载并且解压
mkdir -p /data/db # 这个路径是MongoDB默认的数据存放路径
mongod #启动
数据模型和基本操作
数据库管理命令:
- 显示所有数据库列表:
show dbs
- 切换到指定的数据库:
use <database_name> # 切换到指定数据库(如果不存在则自动创建)
- 删除当前所在的数据库:
db.dropDatabase()
创建数据库和集合 在MongoDB中,数据库和集合是按需自动创建的。当您插入数据时,如果数据库不存在,MongoDB将会自动创建它。 同样,当您插入数据到一个尚不存在的集合时,MongoDB也会自动创建这个集合。
集合管理命令:
- 显示当前数据库中的所有集合:
show collections
- 创建一个新的集合:
db.createCollection("<collection_name>")
(例如:db.createCollection("users")
,将创建名为"users"的集合)
- 删除指定的集合:
db.<collection_name>.drop()
(例如:db.users.drop()
,将删除名为"users"的集合)
文档插入和查询命令:
- 在指定集合中插入一个文档:
db.<collection_name>.insertOne(<document>)
(例如:db.users.insertOne({ name: "John", age: 30, email: "john@example.com" })
)
- 在指定集合中插入多个文档:
db.<collection_name>.insertMany([<document1>, <document2>, ...])
(例如:db.users.insertMany([{ name: "Alice", age: 25 }, { name: "Bob", age: 35 }])
)
- 查询指定集合中的所有文档:
db.<collection_name>.find()
(例如:db.users.find()
)
- 根据查询条件查询指定集合中的文档:
db.<collection_name>.find(<query>)
(例如:db.users.find({ age: { $gt: 25 } })
,将查询年龄大于25岁的用户)
- 返回符合查询条件的第一个文档:
db.<collection_name>.findOne(<query>)
(例如:db.users.findOne({ name: "John" })
,将返回名为"John"的用户的第一个匹配文档)
文档更新和删除命令
- 更新符合条件的第一个文档:
db.<collection_name>.updateOne(<filter>, <update>)
(例如:db.users.updateOne({ name: "John" }, { $set: { age: 32 } })
,将更新名为"John"的用户的年龄为32岁)
- 更新符合条件的所有文档:
db.<collection_name>.updateMany(<filter>, <update>)
(例如:db.users.updateMany({ age: { $gt: 30 } }, { $set: { status: "adult" } })
,将年龄大于30岁的用户设置状态为"adult")
- 替换符合条件的第一个文档:
db.<collection_name>.replaceOne(<filter>, <replacement>)
(例如:db.users.replaceOne({ name: "Alice" }, { name: "Alice", age: 26, email: "alice@example.com" })
,将替换名为"Alice"的用户的所有信息)
- 删除符合条件的第一个文档:
db.<collection_name>.deleteOne(<filter>)
(例如:db.users.deleteOne({ name: "Bob" })
,将删除名为"Bob"的用户的第一个匹配文档)
- 删除符合条件的所有文档:
db.<collection_name>.deleteMany(<filter>)
(例如:db.users.deleteMany({ age: { $lt: 18 } })
,将删除年龄小于18岁的所有用户)
索引操作命令
- 在指定集合上创建索引:
db.<collection_name>.createIndex(<index_spec>)
(例如:db.users.createIndex({ name: 1 })
,将在"users"集合的"name"字段上创建升序索引)
- 显示指定集合上的所有索引:
db.<collection_name>.getIndexes()
(例如:db.users.getIndexes()
)
- 删除指定集合上的索引:
db.<collection_name>.dropIndex(<index_name>)
(例如:db.users.dropIndex("name_1")
,将删除名为"name_1"的索引)
查询语言
整个文档查询:
db.inventory.find({}) 查询所有的文档
db.inventory.find({}).pretty() 返回格式化后的文档
条件查询:
- 精准等值查询
db.inventory.find( { status: "D" } );
db.inventory.find( { qty: 0 } );
- 多条件查询
db.inventory.find( { qty: 0, status: "D" } );
- 嵌套对象精准查询
db.inventory.find( { "size.uom": "in" } );
- 返回指定字段
db.inventory.find( { }, { item: 1, status: 1 } );
默认会返回_id 字段, 同样可以通过指定 _id:0 ,不返回_id 字段
- 条件查询 and
db.inventory.find({$and:[{"qty":0},{"status":"A"}]}).pretty();
- 条件查询 or
db.inventory.find({$or:[{"qty":0},{"status":"A"}]}).pretty();
Mongo查询条件和SQL查询对照表
SQL | MQL |
a<>1 或者 a!=1 | { a : {$ne: 1}} |
a>1 | { a: {$gt:1}} |
a>=1 | { a: {$gte:1}} |
a<1 | { a: {$lt:1}} |
a<=1 | { a: { $lte:1}} |
in | { a: { $in:[ x, y, z]}} |
not in | { a: { $nin:[ x, y, z]}} |
a is null | { a: { $exists: false }} |
索引和性能优化
什么是索引?
在MongoDB中,索引是一种特殊的数据结构,用于加快数据查询的速度。索引可以类比于书籍的目录,它们提供了关键词和对应页面的映射,使得我们能够更快地找到所需的信息。在数据库中,索引允许数据库引擎快速定位和访问特定字段的值,从而提高查询性能。
MongoDB支持多种类型的索引,其中最常见的是单字段索引和复合索引。单字段索引是对单个字段创建的索引,而复合索引则是对多个字段创建的组合索引。
创建索引
在MongoDB中,可以使用createIndex()
方法来创建索引。以下是创建单字段索引和复合索引的示例:
创建单字段索引:
db.your_collection_name.createIndex({ field: 1 })
其中,field
是您想要创建索引的字段名,1
表示创建升序索引,-1
表示创建降序索引。
创建复合索引:
db.your_collection_name.createIndex({ field1: 1, field2: -1 })
在这个例子中,对field1
字段创建升序索引,对field2
字段创建降序索引,以形成复合索引。
索引策略和优化技巧
在使用索引时,以下是一些优化技巧和策略,可以帮助您提高数据库性能:
-
选择适当的字段创建索引: 对于经常进行查询的字段,考虑创建索引以加快查询速度。但不要过度使用索引,因为索引会增加写入操作的成本。
-
复合索引优化: 复合索引可以覆盖多个字段,但要确保索引的字段顺序和查询条件一致,这样索引能够最有效地支持查询。
-
避免全文索引过多文本: 全文索引适用于文本字段,但对于较大的文本内容,会导致索引变得庞大,影响性能。应该根据实际需求选择是否使用全文索引。
-
定期重建索引: 长期运行的数据库可能会因为数据增长和删除而导致索引不再高效。定期重建索引可以帮助维持查询性能。
-
监控索引性能: 使用MongoDB的性能监控工具,如
explain()
方法,来查看查询执行计划和索引使用情况,从而优化查询性能。 -
避免大事务: 大事务可能导致较长时间的锁定,影响索引的更新和查询效率。建议尽量使用小事务来减少锁定时间。
-
使用索引提示: 在一些复杂查询场景下,可以使用索引提示(hint)来指定查询使用特定的索引,从而避免MongoDB自动选择索引的开销。
请注意,优化索引是一个复杂的过程,需要根据具体的业务需求和数据库使用情况进行调整。在进行索引优化时,最好进行测试和监控,以确保达到预期的性能提升。同时,MongoDB的版本和配置也会影响索引的性能,因此建议参考官方文档和最佳实践指南进行优化。
安全性
访问控制和权限管理
MongoDB提供了一系列安全措施来保护数据免受未经授权的访问和恶意行为。在MongoDB中,访问控制和权限管理的主要工具是基于角色的访问控制(Role-Based Access Control,RBAC)。
创建管理员用户:
use admin
db.createUser({
user: "adminUser",
pwd: "adminPassword",
roles: ["root"]
})
创建普通用户:
use your_database_name
db.createUser({
user: "userName",
pwd: "userPassword",
roles: ["readWrite"]
})
以上示例分别创建了一个拥有"root"角色的管理员用户和一个拥有"readWrite"角色的普通用户。"root"角色拥有最高级别的权限,可以管理所有数据库和执行敏感操作。"readWrite"角色则允许用户读取和写入特定数据库。
用户身份认证:
在MongoDB配置文件中启用身份认证后,用户在连接数据库时需要提供正确的用户名和密码才能访问数据库。这样可以确保只有经过身份认证的用户才能使用数据库。
加密通信
保护数据库通信的机密性和完整性对于数据安全至关重要。在MongoDB中,您可以使用SSL/TLS(安全套接字层/传输层安全)来加密数据传输。
启用SSL/TLS:
-
获取证书和密钥:首先,您需要获得用于加密通信的证书和密钥。可以自签名证书,也可以购买有效的SSL证书。
-
配置MongoDB:编辑MongoDB的配置文件,启用SSL选项,并提供证书和密钥的路径。
-
重启MongoDB:重启MongoDB服务使配置生效。
启用SSL/TLS后,MongoDB将通过加密通道传输数据,确保传输的数据在传输过程中是安全和私密的。
需要注意的是,虽然加密通信和访问控制可以显著提高MongoDB的安全性,但数据安全是一个持续的过程。除了加密通信和访问控制外,还需要定期更新和维护系统,确保MongoDB版本更新到最新,同时实施网络安全和其他安全措施来保护数据库免受恶意攻击。
MongoDB与其他工具和语言的集成
使用Python操作MongoDB
Python是一种广泛使用的编程语言,与MongoDB的集成非常方便。您可以使用PyMongo库来在Python中操作MongoDB数据库。
安装PyMongo:
使用pip来安装PyMongo:
pip install pymongo
连接到MongoDB:
import pymongo
# 建立与MongoDB的连接
client = pymongo.MongoClient("mongodb://localhost:27017/")
# 选择数据库
db = client["your_database_name"]
# 选择集合
collection = db["your_collection_name"]
插入数据:
data = {
"name": "John",
"age": 30,
"email": "john@example.com"
}
# 插入单个文档
collection.insert_one(data)
查询数据:
# 查询所有文档
all_documents = collection.find()
# 查询满足条件的文档
query = {"name": "John"}
result = collection.find(query)
使用Node.js操作MongoDB
Node.js是一种流行的服务器端JavaScript运行环境,它也能方便地操作MongoDB数据库。您可以使用官方的MongoDB Node.js驱动程序来实现Node.js与MongoDB的集成。
安装MongoDB Node.js驱动程序:
使用npm来安装MongoDB Node.js驱动程序:
npm install mongodb
连接到MongoDB:
const MongoClient = require('mongodb').MongoClient;
// 连接到MongoDB
const uri = "mongodb://localhost:27017/";
const client = new MongoClient(uri, { useNewUrlParser: true });
// 选择数据库和集合
client.connect(err => {
const db = client.db("your_database_name");
const collection = db.collection("your_collection_name");
});
插入数据:
const data = {
name: "John",
age: 30,
email: "john@example.com"
};
// 插入单个文档
collection.insertOne(data, function(err, result) {
if (err) throw err;
console.log("Inserted document with _id: " + result.insertedId);
});
查询数据:
// 查询所有文档
collection.find({}).toArray(function(err, docs) {
if (err) throw err;
console.log(docs);
});
// 查询满足条件的文档
collection.find({ name: "John" }).toArray(function(err, docs) {
if (err) throw err;
console.log(docs);
});
使用MongoDB与Elasticsearch集成
MongoDB和Elasticsearch是两个不同的数据库系统,各自有自己的特点和用途。MongoDB适合存储和查询复杂的非结构化数据,而Elasticsearch则适合进行全文搜索和实时数据分析。
在某些场景下,您可能希望将MongoDB和Elasticsearch集成,以充分发挥它们各自的优势。有几种方法可以实现MongoDB与Elasticsearch集成:
-
同步数据: 您可以编写脚本或使用工具定期从MongoDB中读取数据,并将其同步到Elasticsearch中。这样就可以在Elasticsearch中进行全文搜索和实时数据分析。
-
使用Logstash: Logstash是Elastic Stack的一部分,是一个功能强大的数据处理工具。您可以使用Logstash作为数据传输管道,从MongoDB中获取数据并将其发送到Elasticsearch进行索引。
-
使用MongoDB的Elasticsearch Connector: MongoDB提供了一个Elasticsearch连接器,它允许您实时地将MongoDB数据传输到Elasticsearch中进行全文搜索。
在决定使用哪种集成方法时,需要考虑数据一致性、数据同步频率、性能和资源等因素。集成MongoDB和Elasticsearch可以使您的应用程序更加灵活和强大,为用户提供更好的搜索和分析体验。
Spring Boot整合MongoDB
与Spring Boot整合MongoDB和Elasticsearch可以实现在Spring Boot应用程序中使用这两个数据库的功能。Spring Boot提供了集成MongoDB和Elasticsearch的支持,使得在应用程序中操作这两个数据库变得简单和高效。下面分别介绍如何与Spring Boot整合MongoDB和Elasticsearch:
1. Spring Boot整合MongoDB
添加MongoDB依赖:
在pom.xml
文件中添加Spring Boot对MongoDB的依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
配置MongoDB连接:
在application.properties
或application.yml
文件中配置MongoDB连接信息:
spring.data.mongodb.uri=mongodb://localhost:27017/your_database_name
创建实体类:
创建一个Java实体类,表示MongoDB中的文档:
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
@Document(collection = "your_collection_name")
public class YourEntity {
@Id
private String id;
private String name;
private int age;
private String email;
// Getters and setters
}
使用MongoDB Repository:
创建一个继承自MongoRepository
的接口,用于定义MongoDB数据库操作:
import org.springframework.data.mongodb.repository.MongoRepository;
public interface YourRepository extends MongoRepository<YourEntity, String> {
// 可以在这里定义自定义查询方法
}
现在,您可以在Spring Boot的服务层或控制层中使用YourRepository
来对MongoDB进行增删改查操作。
2. Spring Boot整合Elasticsearch
添加Elasticsearch依赖:
在pom.xml
文件中添加Spring Boot对Elasticsearch的依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
配置Elasticsearch连接:
在application.properties
或application.yml
文件中配置Elasticsearch连接信息:
spring.data.elasticsearch.cluster-nodes=localhost:9300
创建Elasticsearch实体类:
创建一个Java实体类,表示Elasticsearch中的文档:
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
@Document(indexName = "your_index_name", type = "your_type_name")
public class YourEntity {
@Id
private String id;
private String name;
private int age;
private String email;
// Getters and setters
}
使用Elasticsearch Repository:
创建一个继承自ElasticsearchRepository
的接口,用于定义Elasticsearch数据库操作:
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
public interface YourRepository extends ElasticsearchRepository<YourEntity, String> {
// 可以在这里定义自定义查询方法
}
现在,您可以在Spring Boot的服务层或控制层中使用YourRepository
来对Elasticsearch进行增删改查操作。
3. 整合MongoDB和Elasticsearch
在Spring Boot中同时使用MongoDB和Elasticsearch时,需要在项目中配置多个数据源,并在每个Repository接口上使用@Qualifier
注解来指定具体的数据源。这样可以确保每个Repository使用正确的数据源进行操作。
整合MongoDB和Elasticsearch使得您可以根据实际需求,灵活地选择存储和查询数据。例如,您可以将非结构化的数据存储在MongoDB中,并使用Elasticsearch进行全文搜索和实时数据分析。整合这两个数据库可以为您的应用程序带来更强大和高效的数据处理能力。
示例项目
示例项目:基于Python的MongoDB驱动Web应用程序
在本示例项目中,我们将使用Python和MongoDB来构建一个简单的Web应用程序。我们将使用Python的Flask框架来搭建Web应用,并使用PyMongo库来连接和操作MongoDB数据库。我们假设您已经安装了Python和MongoDB,并正确配置了MongoDB的连接。
步骤1:安装Flask和PyMongo
首先,我们需要安装Flask和PyMongo库。使用以下命令通过pip安装它们:
pip install Flask pymongo
步骤2:编写Flask应用程序
创建一个名为app.py的Python文件,并添加以下代码:
from flask import Flask, request, jsonify
from pymongo import MongoClient
app = Flask(__name__)
# MongoDB连接配置
client = MongoClient('mongodb://localhost:27017/')
db = client['mydatabase']
collection = db['users']
# 路由:添加用户
@app.route('/users', methods=['POST'])
def add_user():
data = request.json
result = collection.insert_one(data)
return jsonify({"message": "User added successfully", "id": str(result.inserted_id)}), 201
# 路由:获取所有用户
@app.route('/users', methods=['GET'])
def get_users():
users = list(collection.find({}, {'_id': 0}))
return jsonify(users), 200
if __name__ == '__main__':
app.run(debug=True)
步骤3:运行应用程序
在命令行中执行以下命令来运行应用程序:
python app.py
Flask应用程序将会运行在http://127.0.0.1:5000/。现在,您可以使用cURL或Postman等工具来测试这个简单的Web应用程序。
使用cURL测试添加用户功能:
curl -X POST -H "Content-Type: application/json" -d '{"name": "John", "age": 30, "email": "john@example.com"}' http://127.0.0.1:5000/users
使用cURL测试获取所有用户功能:
curl http://127.0.0.1:5000/users
您将能够看到从MongoDB数据库中添加和获取用户数据的结果。
示例项目:基于Node.js的MongoDB驱动Web应用程序
在本示例项目中,我们将使用Node.js和MongoDB来构建一个简单的Web应用程序。我们将使用Express框架来搭建Web应用,并使用MongoDB的官方驱动程序(mongodb)来连接和操作MongoDB数据库。我们假设您已经安装了Node.js和MongoDB,并正确配置了MongoDB的连接。
步骤1:创建项目文件夹并初始化项目
首先,创建一个新的项目文件夹并初始化Node.js项目。在命令行中执行以下命令:
mkdir nodejs-mongodb-webapp
cd nodejs-mongodb-webapp
npm init -y
步骤2:安装Express和MongoDB驱动程序
使用以下命令安装Express和MongoDB驱动程序:
npm install express mongodb
步骤3:编写Express应用程序
创建一个名为app.js的JavaScript文件,并添加以下代码:
const express = require('express');
const MongoClient = require('mongodb').MongoClient;
const app = express();
const port = 3000;
// MongoDB连接配置
const uri = 'mongodb://localhost:27017/';
const client = new MongoClient(uri, { useNewUrlParser: true });
let collection;
client.connect((err) => {
if (err) throw err;
const db = client.db('mydatabase');
collection = db.collection('users');
});
// 路由:添加用户
app.post('/users', (req, res) => {
const data = req.body;
collection.insertOne(data, (err, result) => {
if (err) throw err;
res.status(201).json({ message: 'User added successfully', id: result.insertedId });
});
});
// 路由:获取所有用户
app.get('/users', (req, res) => {
collection.find({}, { _id: 0 }).toArray((err, users) => {
if (err) throw err;
res.status(200).json(users);
});
});
app.listen(port, () => {
console.log(`App listening at http://localhost:${port}`);
});
步骤4:运行应用程序
在命令行中执行以下命令来运行应用程序:
node app.js
Express应用程序将会运行在http://localhost:3000/。现在,您可以使用Postman或其他工具来测试这个简单的Web应用程序。
使用Postman测试添加用户功能:
- Method: POST
- URL: http://localhost:3000/users
- Body: raw (JSON) -> {"name": "John", "age": 30, "email": "john@example.com"}
使用Postman测试获取所有用户功能:
- Method: GET
- URL: http://localhost:3000/users
转载自:https://juejin.cn/post/7263867759896100924