MongoDB vs Redis vs Elasticsearch:2026 年 NoSQL 数据库选型指南


阿里云推广

MongoDB vs Redis vs Elasticsearch:2026 年 NoSQL 数据库选型指南

90% 的 NoSQL 选型纠结,本质上是没搞清楚「你要解决什么问题」。这篇文章用 5 个真实场景 + 对比表格 + 完整代码,帮你一次性搞懂 MongoDB、Redis、Elasticsearch 到底该选谁。

一张图搞懂三者的定位

对比维度 MongoDB Redis Elasticsearch
——— ——— ——- ————–
数据模型 文档(BSON/JSON) 键值对 + 数据结构 文档(JSON)
核心能力 灵活存储、事务支持 极速读写、数据结构丰富 全文检索、聚合分析
持久化 磁盘优先,WiredTiger 内存优先,RDB/AOF 可选 磁盘(Lucene 倒排索引)
查询语言 MQL(类 SQL) 命令式 API DSL(JSON 格式)
事务支持 4.0+ 支持多文档事务 Lua 脚本保证原子性 不支持跨文档事务
典型 QPS 万级 十万级 千级(复杂查询)
适用场景 通用数据存储 缓存/实时排行榜/会话 搜索/日志/数据分析

一句话总结

  • **MongoDB** — 啥都能存的万能瑞士军刀
  • **Redis** — 快到飞起的内存缓存之王
  • **Elasticsearch** — 搜索和分析的终极武器
  • 场景 1:用户画像存储 → 选 MongoDB

    需求:存储用户资料,字段经常变(今天加个「兴趣爱好」,明天加个「社交账号」),还要按条件查询。

    # pip install pymongo
    from pymongo import MongoClient, ASCENDING, DESCENDING
    
    client = MongoClient("mongodb://localhost:27017")
    db = client["user_profile"]
    users = db["users"]
    
    # 插入 — 字段完全自由,不需要提前建表
    users.insert_many([
        {
            "name": "张三",
            "age": 28,
            "tags": ["Python", "云原生"],
            "address": {"city": "郑州", "district": "金水区"},
        },
        {
            "name": "李四",
            "age": 35,
            "tags": ["Go", "K8s"],
            "company": "某大厂",       # 李四多了个字段,完全没问题
            "address": {"city": "北京", "district": "海淀区"},
        },
    ])
    
    # 灵活查询 — 按城市 + 年龄范围
    results = users.find({
        "address.city": "郑州",
        "age": {"$gte": 25, "$lte": 30},
    }).sort("age", ASCENDING)
    
    for r in results:
        print(r)
    
    # 建索引加速
    users.create_index([("address.city", ASCENDING), ("age", ASCENDING)])
    
    # 更新 — 给所有郑州用户加个标签
    users.update_many(
        {"address.city": "郑州"},
        {"$addToSet": {"tags": "河南老乡"}},
    )

    为什么不用 Redis? Redis 存复杂嵌套结构要手动序列化,查询能力弱。

    为什么不用 ES? ES 更适合搜索,不是通用存储引擎,写放大问题明显。

    场景 2:实时排行榜 + 限流 → 选 Redis

    需求:游戏排行榜 Top 100,API 限流每用户 100 次/分钟。

    # pip install redis
    import redis
    import time
    import json
    
    r = redis.Redis(host="localhost", port=6379, db=0, decode_responses=True)
    
    # ===== 排行榜:用 Sorted Set =====
    leaderboard_key = "game:ranking:season1"
    
    # 批量添加分数
    r.zadd(leaderboard_key, {
        "player_001": 9800,
        "player_002": 12500,
        "player_003": 11000,
        "player_004": 8900,
        "player_005": 15000,
    })
    
    # 增加某玩家分数
    r.zincrby(leaderboard_key, 300, "player_001")
    
    # 获取 Top 3(分数从高到低)
    top3 = r.zrevrange(leaderboard_key, 0, 2, withscores=True)
    print("🏆 Top 3:")
    for name, score in top3:
        print(f"  {name}: {int(score)} 分")
    
    # 查某玩家排名
    rank = r.zrevrank(leaderboard_key, "player_001")
    print(f"player_001 排名: 第 {rank + 1} 名")
    
    
    # ===== API 限流:用 String + TTL =====
    def check_rate_limit(user_id: str, max_requests: int = 100, window: int = 60) -> bool:
        """滑动窗口限流:每用户每分钟最多 max_requests 次请求"""
        key = f"rate_limit:{user_id}"
        current = r.get(key)
        if current is None:
            r.setex(key, window, 1)
            return True
        if int(current) >= max_requests:
            return False
        r.incr(key)
        return True
    
    # 测试限流
    for i in range(105):
        allowed = check_rate_limit("user_123", max_requests=100)
        if not allowed:
            print(f"🚫 第 {i+1} 次请求被限流")
            break

    为什么不用 MongoDB? 排行榜需要实时排序,MongoDB 排序要走磁盘,性能差几个数量级。

    为什么不用 ES? 限流需要毫秒级读写,ES 的写入延迟不适合。

    场景 3:商品搜索 + 聚合分析 → 选 Elasticsearch

    需求:电商商品搜索,支持中文分词、多条件筛选、价格聚合。

    # pip install elasticsearch
    from elasticsearch import Elasticsearch
    from elasticsearch.helpers import bulk
    
    es = Elasticsearch("http://localhost:9200")
    
    # 创建索引,配置中文分词器
    index_name = "products"
    if es.indices.exists(index=index_name):
        es.indices.delete(index=index_name)
    
    es.indices.create(index=index_name, body={
        "settings": {
            "analysis": {
                "analyzer": {
                    "ik_smart_analyzer": {
                        "type": "custom",
                        "tokenizer": "ik_max_word"    # 需要安装 ik 分词插件
                    }
                }
            }
        },
        "mappings": {
            "properties": {
                "name": {"type": "text", "analyzer": "ik_smart_analyzer"},
                "category": {"type": "keyword"},
                "price": {"type": "float"},
                "brand": {"type": "keyword"},
                "tags": {"type": "keyword"},
            }
        }
    })
    
    # 批量写入商品
    products = [
        {"name": "腾讯云轻量应用服务器 2核4G", "category": "云服务器", "price": 68.0, "brand": "腾讯云", "tags": ["入门", "高性价比"]},
        {"name": "阿里云 ECS 通用型 4核8G", "category": "云服务器", "price": 156.0, "brand": "阿里云", "tags": ["企业级", "稳定"]},
        {"name": "华为云耀云服务器 2核2G", "category": "云服务器", "price": 49.0, "brand": "华为云", "tags": ["入门", "低价"]},
        {"name": "大模型 API 调用包 100万 Token", "category": "AI 服务", "price": 29.9, "brand": "混元", "tags": ["AI", "大模型"]},
    ]
    
    actions = [
        {"_index": index_name, "_source": p}
        for p in products
    ]
    bulk(es, actions)
    
    # 搜索:云服务器 + 价格 < 100
    result = es.search(index=index_name, body={
        "query": {
            "bool": {
                "must": [
                    {"match": {"name": "云服务器"}},
                ],
                "filter": [
                    {"range": {"price": {"lte": 100}}}
                ]
            }
        },
        "aggs": {
            "brand_stats": {
                "terms": {"field": "brand", "size": 10}
            },
            "price_ranges": {
                "range": {
                    "field": "price",
                    "ranges": [
                        {"key": "0-50", "to": 50},
                        {"key": "50-100", "from": 50, "to": 100},
                        {"key": "100+", "from": 100},
                    ]
                }
            }
        }
    })
    
    print("搜索结果:")
    for hit in result["hits"]["hits"]:
        src = hit["_source"]
        print(f"  {src['name']} - ¥{src['price']} ({src['brand']})")
    
    print("\n品牌分布:")
    for bucket in result["aggregations"]["brand_stats"]["buckets"]:
        print(f"  {bucket['key']}: {bucket['doc_count']} 个商品")

    为什么不用 MongoDB? MongoDB 的文本搜索能力有限,中文分词支持差,聚合分析不如 ES 灵活。

    为什么不用 Redis? Redis 的搜索模块(RediSearch)功能远不如 ES,生态差距大。

    场景 4:混合架构 — 三者搭配才是王道

    真实项目往往是三者搭配使用:

    层次 技术 职责
    —— —— ——
    缓存层 Redis 热点数据缓存、会话管理、限流
    存储层 MongoDB 核心业务数据持久化
    搜索层 Elasticsearch 全文检索、日志分析、数据看板

    数据流转示意

    用户请求 → Redis 缓存命中?
      ├── 是 → 直接返回(< 1ms)
      └── 否 → MongoDB 查询 → 写入 Redis 缓存 → 返回
                    ↓
               异步同步到 ES(用于搜索)
    # 混合架构示例:商品详情查询
    import json
    
    def get_product(product_id: str) -> dict:
        """三级查询:Redis → MongoDB → 返回并缓存"""
    
        # 第 1 级:查 Redis 缓存
        cache_key = f"product:{product_id}"
        cached = r.get(cache_key)
        if cached:
            print("✅ Redis 缓存命中")
            return json.loads(cached)
    
        # 第 2 级:查 MongoDB
        product = db["products"].find_one({"_id": product_id})
        if not product:
            return None
    
        product["_id"] = str(product["_id"])
    
        # 写入 Redis,TTL 5 分钟
        r.setex(cache_key, 300, json.dumps(product, ensure_ascii=False))
        print("📦 MongoDB 查询完成,已写入缓存")
    
        return product

    场景 5:云上部署成本对比

    以腾讯云为例,同等 4C8G 配置的月费:

    服务 腾讯云产品 月费(按量/包年包月)
    —— ———– ———————
    MongoDB 云数据库 MongoDB ¥320 起
    Redis 云数据库 Redis ¥280 起
    Elasticsearch 云搜索服务 ES ¥450 起
    自建(CVM 4C8G) 云服务器 CVM ¥180 起

    自建 vs 托管怎么选?

    对比项 自建 托管(云数据库)
    ——– —— —————–
    运维成本 高(备份、监控、升级全自己来) 低(一键高可用、自动备份)
    初始费用 低(只付 CVM 钱) 高(溢价 50%-100%)
    可靠性 取决于运维水平 SLA 99.95%+
    适合 有运维能力的创业团队 追求稳定的企业

    我的建议:初期用自建快速验证,业务跑起来后迁移到托管,别让运维拖了业务后腿。

    选型决策速查表

    你的需求 选谁
    ——— ——
    通用数据存储,字段经常变 MongoDB
    缓存、会话、排行榜、限流 Redis
    全文搜索、日志分析、数据看板 Elasticsearch
    存 JSON,偶尔按字段查 MongoDB
    延迟要求 < 1ms Redis
    中文搜索 + 聚合统计 Elasticsearch
    需要事务 MongoDB 4.0+
    时序数据 + 实时计算 Redis(TimeSeries 模块)

    小结

    NoSQL 选型的核心逻辑就三句话:

    1. MongoDB — 数据结构复杂、查询灵活,选它不会错

    2. Redis — 追求极致性能、做缓存和实时计算,非它莫属

    3. Elasticsearch — 搜索和分析是刚需,别犹豫

    真正的难题从来不是「选哪个」,而是「你到底要解决什么问题」。搞清楚需求,选型自然就清晰了。


    👤 作者简介

    一枚在大中原腹地(河南)卖公有云的从业者,主营腾讯云/阿里云/火山云,曾踩坑无数,现专注AI大模型应用落地。关注公众号「公有云cloud」,围观AI前沿动态~

    博客:yunduancloud.icu

    发表评论