Skip to content

MongoDB 入门

MongoDB 是一种流行的 NoSQL 数据库,它使用文档模型存储数据。本文将介绍 MongoDB 的核心概念和基本操作。

1. 基本概念

什么是 MongoDB

MongoDB 是一种开源的 NoSQL 数据库,它使用文档模型存储数据,而不是传统的表格结构。MongoDB 的文档是 JSON 格式的,这使得它非常灵活和易于使用。

核心概念

  • 数据库 (Database):存储文档的容器
  • 集合 (Collection):文档的集合,类似于关系型数据库的表格
  • 文档 (Document):数据的基本单位,是 JSON 格式的对象
  • 字段 (Field):文档中的键值对
  • 索引 (Index):提高查询性能
  • 聚合 (Aggregation):数据处理和分析

2. 安装与配置

安装 MongoDB

Windows

  1. 访问 MongoDB 官网
  2. 下载 MongoDB Community Server
  3. 运行安装程序,按照提示完成安装
  4. 启动 MongoDB 服务

macOS

  1. 使用 Homebrew 安装:brew install mongodb-community
  2. 启动 MongoDB 服务:brew services start mongodb-community

Linux

  1. 按照 MongoDB 官网的说明安装
  2. 启动 MongoDB 服务:sudo systemctl start mongod

配置 MongoDB

MongoDB 的配置文件通常位于:

  • Windows:C:\Program Files\MongoDB\Server\version\bin\mongod.cfg
  • macOS:/usr/local/etc/mongod.conf
  • Linux:/etc/mongod.conf

3. 基本操作

启动 MongoDB Shell

bash
mongo

数据库操作

javascript
-- 显示所有数据库
show dbs

-- 切换到指定数据库(如果不存在则创建)
use mydb

-- 显示当前数据库
db

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

集合操作

javascript
-- 创建集合
db.createCollection('users')

-- 显示所有集合
show collections

-- 删除集合
db.users.drop()

文档操作

插入文档

javascript
-- 插入单条文档
db.users.insertOne({
  name: 'John Doe',
  email: 'john@example.com',
  age: 30,
  address: {
    street: '123 Main St',
    city: 'New York',
    state: 'NY'
  },
  hobbies: ['reading', 'swimming', 'hiking']
})

-- 插入多条文档
db.users.insertMany([
  {
    name: 'Jane Smith',
    email: 'jane@example.com',
    age: 25
  },
  {
    name: 'Bob Johnson',
    email: 'bob@example.com',
    age: 35
  }
])

查询文档

javascript
-- 查询所有文档
db.users.find()

-- 查询指定条件的文档
db.users.find({ age: { $gt: 25 } })

-- 查询单个文档
db.users.findOne({ name: 'John Doe' })

-- 投影(只返回指定字段)
db.users.find({}, { name: 1, email: 1 })

-- 排序
db.users.find().sort({ age: 1 })  // 升序
db.users.find().sort({ age: -1 }) // 降序

-- 限制结果数量
db.users.find().limit(5)

-- 跳过结果
db.users.find().skip(5)

更新文档

javascript
-- 更新单个文档
db.users.updateOne(
  { name: 'John Doe' },
  { $set: { age: 31 } }
)

-- 更新多个文档
db.users.updateMany(
  { age: { $gt: 30 } },
  { $set: { status: 'senior' } }
)

-- 替换文档
db.users.replaceOne(
  { name: 'John Doe' },
  {
    name: 'John Doe',
    email: 'john.doe@example.com',
    age: 31
  }
)

删除文档

javascript
-- 删除单个文档
db.users.deleteOne({ name: 'John Doe' })

-- 删除多个文档
db.users.deleteMany({ age: { $gt: 30 } })

-- 删除所有文档
db.users.deleteMany({})

4. 查询操作符

比较操作符

  • $eq:等于
  • $ne:不等于
  • $gt:大于
  • $gte:大于等于
  • $lt:小于
  • $lte:小于等于
  • $in:在指定数组中
  • $nin:不在指定数组中

逻辑操作符

  • $and:与
  • $or:或
  • $not:非
  • $nor:既不...也不

元素操作符

  • $exists:字段存在
  • $type:字段类型

数组操作符

  • $all:数组包含所有指定值
  • $elemMatch:数组元素匹配指定条件
  • $size:数组大小

其他操作符

  • $regex:正则表达式
  • $text:文本搜索
  • $geoWithin:地理空间查询

5. 索引

创建索引

javascript
-- 创建单字段索引
db.users.createIndex({ name: 1 })  // 升序
db.users.createIndex({ name: -1 }) // 降序

-- 创建复合索引
db.users.createIndex({ name: 1, age: -1 })

-- 创建唯一索引
db.users.createIndex({ email: 1 }, { unique: true })

-- 创建文本索引
db.users.createIndex({ name: 'text', email: 'text' })

-- 创建地理空间索引
db.places.createIndex({ location: '2dsphere' })

查看索引

javascript
-- 查看集合的索引
db.users.getIndexes()

删除索引

javascript
-- 删除指定索引
db.users.dropIndex({ name: 1 })

-- 删除所有索引(除了 _id 索引)
db.users.dropIndexes()

6. 聚合

聚合管道

javascript
-- 基本聚合
db.users.aggregate([
  { $match: { age: { $gt: 25 } } },
  { $group: { _id: '$age', count: { $sum: 1 } } },
  { $sort: { count: -1 } }
])

-- 其他聚合操作
-- $project:投影
-- $unwind:展开数组
-- $lookup:左连接
-- $limit:限制结果
-- $skip:跳过结果

示例:计算每个年龄段的用户数量

javascript
db.users.aggregate([
  { $match: { age: { $exists: true } } },
  { $group: { _id: { $floor: { $divide: ['$age', 10] } }, count: { $sum: 1 } } },
  { $project: { age_group: { $concat: [{ $toString: { $multiply: ['$_id', 10] } }, '-', { $toString: { $add: [{ $multiply: ['$_id', 10] }, 9] } }], count: 1, _id: 0 } },
  { $sort: { age_group: 1 } }
])

7. 复制集

复制集概念

复制集是一组 MongoDB 服务器,它们维护相同的数据副本。复制集提供了数据冗余和高可用性。

  • 主节点 (Primary):处理所有写操作
  • 从节点 (Secondary):复制主节点的数据,处理读操作
  • 仲裁节点 (Arbiter):不存储数据,只参与选举

复制集配置

  1. 启动多个 MongoDB 实例
  2. 初始化复制集
  3. 添加成员到复制集

8. 分片

分片概念

分片是将数据分布到多个服务器的过程,它可以提高 MongoDB 的水平扩展性。

  • 分片键:用于确定数据分布的字段
  • 分片服务器:存储数据的服务器
  • 路由服务器:处理客户端请求,将请求路由到正确的分片
  • 配置服务器:存储分片集群的元数据

分片配置

  1. 启动配置服务器
  2. 启动路由服务器
  3. 启动分片服务器
  4. 启用分片
  5. 选择分片键

9. 与 Node.js 集成

安装 MongoDB 驱动

bash
npm install mongodb

基本操作

javascript
const { MongoClient } = require('mongodb');

// 连接到 MongoDB
const uri = 'mongodb://localhost:27017';
const client = new MongoClient(uri);

async function main() {
  try {
    // 连接到数据库
    await client.connect();
    console.log('Connected to MongoDB');

    // 选择数据库和集合
    const db = client.db('mydb');
    const users = db.collection('users');

    // 插入文档
    await users.insertOne({
      name: 'John Doe',
      email: 'john@example.com',
      age: 30
    });

    // 查询文档
    const result = await users.find({ age: { $gt: 25 } }).toArray();
    console.log('Users older than 25:', result);

    // 更新文档
    await users.updateOne(
      { name: 'John Doe' },
      { $set: { age: 31 } }
    );

    // 删除文档
    await users.deleteOne({ name: 'John Doe' });
  } finally {
    // 关闭连接
    await client.close();
  }
}

main().catch(console.error);

10. 最佳实践

数据模型设计

  • 文档结构:设计合理的文档结构,避免过度嵌套
  • 分片键选择:选择高基数、均匀分布的分片键
  • 索引设计:创建适当的索引,提高查询性能
  • 数据备份:定期备份数据,防止数据丢失

查询优化

  • 使用索引:确保查询条件上有索引
  • 限制结果:使用 limit() 限制返回的行数
  • 投影:只返回需要的字段
  • 避免全集合扫描:使用索引减少扫描范围

性能优化

  • 批量操作:使用批量操作减少网络开销
  • 连接池:使用连接池管理数据库连接
  • 监控:监控 MongoDB 的性能和健康状况
  • 调整配置:根据服务器资源调整 MongoDB 配置

11. 常见问题与解决方案

连接问题

问题:无法连接到 MongoDB 解决方案

  • 检查 MongoDB 服务是否运行
  • 检查连接字符串是否正确
  • 检查网络连接是否正常

性能问题

问题:查询速度慢 解决方案

  • 创建适当的索引
  • 优化查询语句
  • 考虑分片

数据丢失

问题:数据丢失 解决方案

  • 启用复制集
  • 定期备份数据
  • 使用 writeConcern 确保数据写入

内存使用过高

问题:MongoDB 内存使用过高 解决方案

  • 调整 WiredTiger 缓存大小
  • 优化查询,减少内存使用
  • 考虑分片

12. 工具推荐

管理工具

  • MongoDB Compass:官方 GUI 工具
  • Robo 3T:开源 GUI 工具
  • Studio 3T:商业 GUI 工具

监控工具

  • MongoDB Atlas:云服务,提供监控功能
  • MongoDB Ops Manager:企业级监控工具
  • Prometheus + Grafana:开源监控方案

备份工具

  • mongodump:官方备份工具
  • MongoDB Atlas Backup:云备份服务

13. 总结

MongoDB 是一种强大的 NoSQL 数据库,它使用文档模型存储数据,具有灵活性高、扩展性强等优点。通过学习 MongoDB 的基本概念和操作,我们可以有效地使用 MongoDB 存储和管理数据。

MongoDB 的核心特性包括:

  • 文档模型
  • 灵活的查询
  • 强大的索引
  • 聚合框架
  • 复制集和分片

通过合理的设计和优化,MongoDB 可以为各种应用场景提供高性能、可靠的数据存储服务。