MongoDB是什么?文档数据库与何时选择NoSQL
Database

MongoDB是什么?文档数据库与何时选择NoSQL

MongoDB是以灵活JSON/BSON格式存储数据的文档数据库,适合schema频繁变化的场景。学习CRUD、聚合管道、副本集以及何时选择MongoDB而非PostgreSQL。

系列文章: 数据库
  1. 1 PostgreSQL是什么?世界上最先进的开源关系数据库
  2. 2 MongoDB是什么?文档数据库与何时选择NoSQL
✦ 快速摘要
MongoDB是以灵活JSON/BSON格式存储数据的文档数据库,适合schema频繁变化的场景。学习CRUD、聚合管道、副本集以及何时选择MongoDB而非PostgreSQL。
这篇文章怎么样?

MongoDB是全球领先的文档数据库,以灵活的JSON格式存储数据,而非像SQL那样使用固定表结构。本文解释MongoDB是什么、文档模型的工作原理、聚合管道,以及何时应选择MongoDB而非PostgreSQL。

MongoDB是什么?

MongoDB是一款文档型NoSQL数据库管理系统,诞生于2009年。与SQL不同,MongoDB不将数据存储在固定的行列表中,而是以灵活的JSON文档(实际上是BSON——Binary JSON)形式存储:

JSON
 1{
 2  "_id": "64a1f2...",
 3  "name": "Alice",
 4  "email": "alice@example.com",
 5  "orders": [
 6    { "product": "笔记本电脑", "price": 999 },
 7    { "product": "鼠标", "price": 29 }
 8  ],
 9  "address": {
10    "city": "河内",
11    "district": "还剑"
12  }
13}

单个用户文档内嵌了订单数据——而在SQL中这需要通过多表JOIN才能实现。

文档模型 vs 关系模型

MongoDB(文档型) PostgreSQL(关系型)
存储单元 文档(JSON) 表中的行
Schema 灵活(不固定) 固定(需迁移)
数据关系 嵌入或引用 外键 + JOIN
扩展方式 水平扩展(分片) 垂直扩展(为主)
事务 多文档(4.0+) 完整ACID

使用pymongo进行CRUD(Python)

Python
 1from pymongo import MongoClient
 2
 3client = MongoClient("mongodb://localhost:27017/")
 4db = client["myapp"]
 5users = db["users"]
 6
 7# 插入
 8result = users.insert_one({
 9    "name": "Alice",
10    "email": "alice@example.com",
11    "active": True
12})
13print(result.inserted_id)  # ObjectId('64a1f2...')
14
15# 带条件查询
16active_users = users.find({"active": True}, {"name": 1, "email": 1})
17for user in active_users:
18    print(user)
19
20# 更新
21users.update_one(
22    {"email": "alice@example.com"},
23    {"$set": {"active": False}}
24)
25
26# 删除
27users.delete_one({"email": "alice@example.com"})

使用Mongoose操作Node.js

JavaScript
 1const mongoose = require('mongoose');
 2await mongoose.connect('mongodb://localhost:27017/myapp');
 3
 4const UserSchema = new mongoose.Schema({
 5  name: { type: String, required: true },
 6  email: { type: String, required: true, unique: true },
 7  active: { type: Boolean, default: true },
 8});
 9
10const User = mongoose.model('User', UserSchema);
11
12// 创建
13const user = await User.create({ name: 'Alice', email: 'alice@example.com' });
14
15// 查询
16const activeUsers = await User.find({ active: true }).select('name email');
17
18// 更新
19await User.updateOne({ email: 'alice@example.com' }, { $set: { active: false } });

聚合管道

JavaScript
 1// 按月统计收入
 2db.orders.aggregate([
 3  { $match: { status: "completed" } },
 4  { $group: {
 5      _id: { $month: "$createdAt" },
 6      totalRevenue: { $sum: "$amount" },
 7      orderCount: { $sum: 1 }
 8  }},
 9  { $sort: { "_id": 1 } }
10])

副本集与高可用性

MongoDB副本集由一个主节点(Primary)和一个或多个从节点(Secondary)组成。主节点接收所有写操作;从节点持续从主节点复制数据。若主节点故障,副本集会在几秒内自动选举新的主节点——为应用提供零停机保障。

何时选择MongoDB vs PostgreSQL?

当schema不稳定、数据天然嵌套或需要快速水平扩展时,选择MongoDB。当需要复杂JOIN、完整ACID或重度报表与分析时,选择PostgreSQL

PostgreSQL是什么?领先的关系型数据库管理系统

Elasticsearch是什么?用于全文搜索的分布式搜索引擎

Redis是什么?内存缓存、发布订阅与队列

常见问题Q&A
MongoDB以什么格式存储数据?
MongoDB以BSON(Binary JSON)格式存储数据——这是JSON的二进制扩展格式,额外支持Date、ObjectId、Binary和Decimal128等类型。通过驱动程序操作时,你看到的是普通JSON;MongoDB在存储时自动转换为BSON。
MongoDB支持事务吗?
支持,从MongoDB 4.0(2018年)起。MongoDB在副本集上支持多文档ACID事务,从4.2起在分片集群上也支持。不过MongoDB的事务开销高于PostgreSQL,只有在确实需要原子更新多个文档时才建议使用。
MongoDB中的副本集是什么?
副本集是一组存储相同数据集的MongoDB实例:一个主节点(Primary)接收所有写操作,一个或多个从节点(Secondary)持续从主节点复制数据。若主节点故障,副本集会在几秒内自动选举新的主节点——这是MongoDB基本的高可用机制。
什么是聚合管道?
聚合管道是一系列按顺序处理数据的阶段:$match(过滤文档)、$group(聚合计算,如COUNT、SUM、AVG)、$sort、$project(选择字段)、$lookup(与其他集合JOIN)。每个阶段接收上一阶段的输出,从而构建复杂的分析查询。
什么时候应该选择MongoDB而非PostgreSQL?
在以下情况选择MongoDB:schema经常变化或尚未明确(敏捷开发)、数据天然具有嵌套结构(每个品类属性不同的商品目录)、需要通过分片快速水平扩展,或团队比起SQL更熟悉JavaScript/JSON。在需要复杂JOIN、严格ACID保证或数据关系紧密时选择PostgreSQL。
MongoDB Atlas是什么?
MongoDB Atlas是云端(AWS、GCP、Azure)完全托管的MongoDB服务。Atlas自动处理备份、扩缩容、安全补丁和监控。提供免费套餐(M0:512MB),适合学习和原型开发。生产环境通常使用M10及以上的专用集群。

MongoDB is the world's leading document database, storing data as flexible JSON instead of fixed tables like SQL. This article explains what MongoDB is, how the document model works, the Aggregation Pipeline, and when to choose MongoDB over PostgreSQL.

What is MongoDB?

MongoDB is a document NoSQL database management system, created in 2009. Instead of storing data in tables with fixed rows and columns like SQL, MongoDB stores data as flexible JSON documents (technically BSON — Binary JSON):

JSON
 1{
 2  "_id": "64a1f2...",
 3  "name": "Alice",
 4  "email": "alice@example.com",
 5  "orders": [
 6    { "product": "Laptop", "price": 999 },
 7    { "product": "Mouse", "price": 29 }
 8  ],
 9  "address": {
10    "city": "Hanoi",
11    "district": "Hoan Kiem"
12  }
13}

A single user document contains embedded orders — something that is unnatural in SQL and requires JOINs across multiple tables.

Document Model vs Relational Model

MongoDB (Document) PostgreSQL (Relational)
Storage unit Document (JSON) Row in a table
Schema Flexible (not fixed) Fixed (requires migration)
Data relationships Embed or reference Foreign key + JOIN
Scaling Horizontal (sharding) Vertical (primarily)
Transactions Multi-document (4.0+) Full ACID

CRUD with pymongo (Python)

Python
 1from pymongo import MongoClient
 2
 3client = MongoClient("mongodb://localhost:27017/")
 4db = client["myapp"]
 5users = db["users"]
 6
 7# Insert
 8result = users.insert_one({
 9    "name": "Alice",
10    "email": "alice@example.com",
11    "active": True
12})
13print(result.inserted_id)  # ObjectId('64a1f2...')
14
15# Find with filter
16active_users = users.find({"active": True}, {"name": 1, "email": 1})
17for user in active_users:
18    print(user)
19
20# Update
21users.update_one(
22    {"email": "alice@example.com"},
23    {"$set": {"active": False}}
24)
25
26# Delete
27users.delete_one({"email": "alice@example.com"})

Node.js with Mongoose

JavaScript
 1const mongoose = require('mongoose');
 2await mongoose.connect('mongodb://localhost:27017/myapp');
 3
 4const UserSchema = new mongoose.Schema({
 5  name: { type: String, required: true },
 6  email: { type: String, required: true, unique: true },
 7  active: { type: Boolean, default: true },
 8});
 9
10const User = mongoose.model('User', UserSchema);
11
12// Create
13const user = await User.create({ name: 'Alice', email: 'alice@example.com' });
14
15// Find
16const activeUsers = await User.find({ active: true }).select('name email');
17
18// Update
19await User.updateOne({ email: 'alice@example.com' }, { $set: { active: false } });

Aggregation Pipeline

JavaScript
 1// Revenue by month
 2db.orders.aggregate([
 3  { $match: { status: "completed" } },
 4  { $group: {
 5      _id: { $month: "$createdAt" },
 6      totalRevenue: { $sum: "$amount" },
 7      orderCount: { $sum: 1 }
 8  }},
 9  { $sort: { "_id": 1 } }
10])

Replica Sets and High Availability

A MongoDB Replica Set consists of one Primary and one or more Secondaries. The Primary accepts all writes; Secondaries continuously replicate from the Primary. If the Primary fails, the Replica Set automatically elects a new Primary within seconds — providing zero downtime for the application.

When to Choose MongoDB vs PostgreSQL?

Choose MongoDB when the schema is unstable, data is naturally nested, or you need fast horizontal scaling. Choose PostgreSQL when you need complex JOINs, full ACID compliance, or heavy reporting and analytics.

What is PostgreSQL? The leading relational database management system

What is Elasticsearch? Distributed search engine for full-text search

What is Redis? In-memory cache, Pub/Sub, and queues

Frequently Asked QuestionsQ&A
What format does MongoDB use to store data?
MongoDB stores data as BSON (Binary JSON) — a binary-encoded extension of JSON that adds types like Date, ObjectId, Binary, and Decimal128. When working through a driver you see regular JSON; MongoDB automatically converts to BSON for storage.
Does MongoDB support transactions?
Yes, since MongoDB 4.0 (2018). MongoDB supports multi-document ACID transactions on replica sets, and since 4.2 on sharded clusters. However, transactions in MongoDB carry higher overhead than PostgreSQL, so use them only when you truly need multiple documents updated atomically.
What is a Replica Set in MongoDB?
A Replica Set is a group of MongoDB instances that maintain the same dataset: one Primary accepts all writes, while one or more Secondaries continuously replicate data from the Primary. If the Primary fails, the Replica Set automatically elects a new Primary within seconds — this is MongoDB's basic high-availability mechanism.
What is the Aggregation Pipeline?
The Aggregation Pipeline is a sequence of data-processing stages run in order: $match (filter documents), $group (aggregate computations like COUNT, SUM, AVG), $sort, $project (select fields), $lookup (JOIN with another collection). Each stage receives the output of the previous stage, enabling complex analytical queries.
When should I choose MongoDB over PostgreSQL?
Choose MongoDB when: the schema changes frequently or is not yet well-defined (agile development), data has naturally nested structures (product catalogs with different attributes per category), you need fast horizontal scaling with sharding, or your team is more comfortable with JavaScript/JSON than SQL. Choose PostgreSQL when you need complex JOINs, strict ACID guarantees, or data with tight relational constraints.
What is MongoDB Atlas?
MongoDB Atlas is a fully managed MongoDB service on the cloud (AWS, GCP, Azure). Atlas automatically handles backups, scaling, security patches, and monitoring. There is a free tier (M0: 512 MB) suitable for learning and prototyping. Production workloads typically use M10 or higher with a dedicated cluster.