聚合管道与复杂查询

目录

  • MongoDB聚合管道与复杂查询:从基础到实战的完整指南
    • [1. 引言](#1. 引言)
    • [2. 聚合管道基础概念](#2. 聚合管道基础概念)
      • [2.1 什么是聚合管道?](#2.1 什么是聚合管道?)
      • [2.2 聚合语法](#2.2 聚合语法)
      • [2.3 聚合阶段分类](#2.3 聚合阶段分类)
    • [3. 核心聚合阶段详解](#3. 核心聚合阶段详解)
      • [3.1 match:数据过滤](#3.1 match:数据过滤)
      • [3.2 project:字段投影与重塑](#3.2 project:字段投影与重塑)
      • [3.3 group:分组聚合](#3.3 group:分组聚合)
      • [3.4 unwind:展开数组](#3.4 unwind:展开数组)
      • [3.5 lookup:多集合关联查询](#3.5 lookup:多集合关联查询)
      • [3.6 s o r t 、 sort、 sort、limit 和 skip:排序与分页](#3.6 s o r t 、 sort、 sort、limit 和 skip:排序与分页)
    • [4. 复杂查询实战案例](#4. 复杂查询实战案例)
      • [4.1 数据模型](#4.1 数据模型)
      • [4.2 案例1:用户消费分析](#4.2 案例1:用户消费分析)
      • [4.3 案例2:商品销售排行](#4.3 案例2:商品销售排行)
      • [4.4 案例3:客户RFM分析](#4.4 案例3:客户RFM分析)
      • [4.5 运行完整示例](#4.5 运行完整示例)
    • [5. 聚合管道性能优化](#5. 聚合管道性能优化)
      • [5.1 优化原则](#5.1 优化原则)
      • [5.2 具体优化策略](#5.2 具体优化策略)
        • [5.2.1 尽早使用 match](#5.2.1 尽早使用 match)
        • [5.2.2 使用 project 减少数据量](#5.2.2 使用 project 减少数据量)
        • [5.2.3 索引设计策略](#5.2.3 索引设计策略)
        • [5.2.4 处理大数据集](#5.2.4 处理大数据集)
      • [5.3 常见性能陷阱](#5.3 常见性能陷阱)
    • [6. 总结](#6. 总结)

『宝藏代码胶囊开张啦!』------ 我的 CodeCapsule 来咯!✨写代码不再头疼!我的新站点 CodeCapsule 主打一个 "白菜价"+"量身定制 "!无论是卡脖子的毕设/课设/文献复现 ,需要灵光一现的算法改进 ,还是想给项目加个"外挂",这里都有便宜又好用的代码方案等你发现!低成本,高适配,助你轻松通关!速来围观 👉 CodeCapsule官网

MongoDB聚合管道与复杂查询:从基础到实战的完整指南

1. 引言

在传统关系型数据库中,我们习惯使用 GROUP BYJOIN 等 SQL 语句来完成复杂的数据分析。MongoDB 作为文档型数据库,提供了更为强大和灵活的 聚合框架(Aggregation Framework) ,它通过 管道(Pipeline) 的概念,让你能够像搭建积木一样,组合多个数据处理阶段,完成从简单过滤到多表关联、数据重塑、统计分析等各种复杂查询。

然而,聚合管道的灵活性也是一把双刃剑。不合理的管道设计(如过早展开数组、缺少索引、阶段顺序错误)可能导致查询缓慢甚至内存溢出。本文将系统性地介绍 MongoDB 聚合管道的核心概念与常用阶段,并通过 Python + PyMongo 的实战示例,帮助你掌握构建高效复杂查询的能力。
集合文档
match 过滤 group 分组聚合
sort 排序 limit 限制结果
最终结果
lookup 关联查询 unwind 展开数组
$project 重塑文档

2. 聚合管道基础概念

2.1 什么是聚合管道?

MongoDB 的聚合框架基于数据处理管道 的概念。文档从集合中读取后,依次通过多个阶段(Stage),每个阶段对文档执行特定的操作(如过滤、分组、转换),然后将处理后的文档传递给下一个阶段。最终,管道输出处理结果。

这种架构的优势在于:

  • 分阶段处理:可以将复杂查询拆解为多个简单步骤,便于理解和调试
  • 内存优化:数据流式处理,无需将所有数据加载到内存
  • 原生操作:直接在数据库端完成计算,减少数据传输

2.2 聚合语法

聚合查询的基本语法如下:

javascript 复制代码
db.collection.aggregate(pipeline, options)

其中:

  • pipeline:一个数组,包含多个聚合阶段
  • options:可选参数,如 allowDiskUse(允许使用磁盘处理大数据)

在 Python 中使用 PyMongo 执行聚合查询:

python 复制代码
pipeline = [
    {"$match": {"status": "active"}},
    {"$group": {"_id": "$category", "count": {"$sum": 1}}}
]
results = db.collection.aggregate(pipeline)
for doc in results:
    print(doc)

2.3 聚合阶段分类

聚合阶段按功能可分为以下四类:

类别 作用 常用阶段
过滤 筛选符合条件的文档 $match
重塑 改变文档结构,添加/删除字段 $project$addFields$unwind
分组 对文档进行分组和统计 $group
关联 连接多个集合 $lookup
排序/分页 控制输出顺序和数量 $sort$limit$skip

3. 核心聚合阶段详解

3.1 $match:数据过滤

$match 阶段用于筛选文档,只保留符合条件的文档继续处理。它应该尽可能放在管道的最前面,这样可以减少后续阶段需要处理的数据量,显著提升性能。

python 复制代码
import pymongo
from pymongo import MongoClient

# 连接数据库
client = MongoClient('mongodb://localhost:27017/')
db = client.shop

# 查找所有状态为"completed"且金额大于100的订单
pipeline = [
    {
        "$match": {
            "status": "completed",
            "total_amount": {"$gt": 100}
        }
    }
]

results = db.orders.aggregate(pipeline)
for order in results:
    print(order)

性能提示$match 中使用的字段应创建索引,特别是当它作为管道的第一阶段时。

3.2 $project:字段投影与重塑

$project 阶段用于控制输出文档中包含哪些字段,以及创建新的计算字段。它可以:

  • 包含/排除字段(1表示包含,0表示排除)
  • 重命名字段
  • 使用表达式创建新字段
python 复制代码
pipeline = [
    {
        "$project": {
            "_id": 0,  # 排除 _id
            "order_id": "$order_no",  # 重命名字段
            "customer_name": 1,  # 保留原字段
            "final_amount": {
                "$multiply": ["$total_amount", 0.9]  # 计算打折后的金额
            },
            "order_year": {"$year": "$created_at"}  # 提取年份
        }
    }
]

results = db.orders.aggregate(pipeline)

在管道的早期使用 $project 可以减少后续阶段需要处理的数据量,是一种重要的优化手段。

3.3 $group:分组聚合

$group 阶段是聚合管道的核心,它根据指定的键对文档进行分组,并对每个组执行聚合计算。

常用聚合操作符

操作符 说明
$sum 求和
$avg 平均值
$min 最小值
$max 最大值
$first 分组内第一个文档的值
$last 分组内最后一个文档的值
$push 将值添加到数组
$addToSet 将值添加到数组(去重)

示例:按月份统计订单金额

python 复制代码
pipeline = [
    {
        "$group": {
            "_id": {
                "year": {"$year": "$created_at"},
                "month": {"$month": "$created_at"}
            },
            "total_orders": {"$sum": 1},
            "total_revenue": {"$sum": "$total_amount"},
            "avg_order_value": {"$avg": "$total_amount"},
            "max_order": {"$max": "$total_amount"},
            "order_ids": {"$push": "$order_no"}  # 收集所有订单号
        }
    },
    {
        "$sort": {"_id.year": 1, "_id.month": 1}
    }
]

stats = db.orders.aggregate(pipeline)

3.4 $unwind:展开数组

当文档中包含数组字段时,$unwind 可以将数组拆分为多个文档,每个文档对应数组中的一个元素。这在处理嵌套数据时非常有用。

python 复制代码
# 示例文档:订单包含多个商品项
{
    "order_no": "ORD001",
    "items": [
        {"product": "鼠标", "price": 99, "qty": 2},
        {"product": "键盘", "price": 199, "qty": 1}
    ]
}

# 展开商品数组,每个商品生成一个文档
pipeline = [
    {"$unwind": "$items"},
    {
        "$project": {
            "order_no": 1,
            "product": "$items.product",
            "subtotal": {"$multiply": ["$items.price", "$items.qty"]}
        }
    }
]

results = db.orders.aggregate(pipeline)
# 输出两个文档:一个对应鼠标,一个对应键盘

注意$unwind 会增加文档数量,因此应尽可能在展开前通过 $match 减少数据量。

3.5 $lookup:多集合关联查询

$lookup 阶段允许在同一个数据库中执行左外连接 操作,类似于 SQL 中的 LEFT JOIN。这对于引用式数据模型特别有用。

基本语法

javascript 复制代码
{
    $lookup: {
        from: "关联集合名称",
        localField: "当前集合中的字段",
        foreignField: "关联集合中的字段",
        as: "输出数组字段名"
    }
}

示例:订单关联用户信息

假设有两个集合:

  • orders:包含 user_id 字段
  • users:包含用户详细信息
python 复制代码
pipeline = [
    {
        "$match": {"status": "completed"}
    },
    {
        "$lookup": {
            "from": "users",
            "localField": "user_id",
            "foreignField": "_id",
            "as": "user_info"
        }
    },
    {
        "$unwind": "$user_info"  # 将数组展开为对象
    },
    {
        "$project": {
            "order_no": 1,
            "total_amount": 1,
            "user_name": "$user_info.name",
            "user_email": "$user_info.email"
        }
    }
]

orders_with_user = db.orders.aggregate(pipeline)

高级用法 :从 MongoDB 3.6 开始,$lookup 支持使用管道进行更复杂的关联条件:

python 复制代码
pipeline = [
    {
        "$lookup": {
            "from": "transactions",
            "let": {"user_id": "$_id", "user_tier": "$tier"},
            "pipeline": [
                {
                    "$match": {
                        "$expr": {
                            "$and": [
                                {"$eq": ["$user_id", "$$user_id"]},
                                {"$gte": ["$amount", 1000]},
                                {"$eq": ["$tier", "$$user_tier"]}
                            ]
                        }
                    }
                },
                {"$limit": 5}
            ],
            "as": "recent_transactions"
        }
    }
]

这种形式的 $lookup 提供了更大的灵活性,可以在关联集合上执行额外的过滤、排序和限制操作。

3.6 s o r t 、 sort、 sort、limit 和 $skip:排序与分页

这些阶段用于控制输出结果的顺序和数量。

python 复制代码
pipeline = [
    {"$match": {"status": "completed"}},
    {"$sort": {"total_amount": -1}},  # 按金额降序
    {"$skip": 20},  # 跳过前20条
    {"$limit": 10}  # 返回10条
]

# 相当于:第21-30条记录

优化提示 :如果需要在排序后分页,尽量在 $match 之后、$group 等重量级操作之前进行 $sort,以减少排序的数据量。同时,为排序字段创建索引可以大幅提升性能。

4. 复杂查询实战案例

本节通过一个电商数据分析的场景,展示如何组合多个聚合阶段解决实际问题。

4.1 数据模型

假设有以下三个集合:

python 复制代码
# users 集合 - 用户信息
{
    "_id": ObjectId("..."),
    "name": "张三",
    "email": "zhangsan@example.com",
    "tier": "gold",  # 会员等级
    "registered_at": ISODate("2023-01-15T08:30:00Z")
}

# orders 集合 - 订单信息
{
    "_id": ObjectId("..."),
    "order_no": "ORD2024001",
    "user_id": ObjectId("..."),
    "status": "completed",
    "total_amount": 1299.99,
    "created_at": ISODate("2024-03-10T14:20:00Z"),
    "items": [
        {"product_id": ObjectId("..."), "name": "智能手机", "price": 999.99, "qty": 1},
        {"product_id": ObjectId("..."), "name": "手机壳", "price": 29.99, "qty": 2}
    ]
}

# products 集合 - 商品信息
{
    "_id": ObjectId("..."),
    "name": "智能手机",
    "category": "电子产品",
    "price": 999.99,
    "stock": 50
}

4.2 案例1:用户消费分析

需求:统计每个会员等级的用户数量、平均消费金额和总消费金额。

python 复制代码
import pymongo
from pymongo import MongoClient
from datetime import datetime, timedelta

client = MongoClient('mongodb://localhost:27017/')
db = client.ecommerce

def analyze_user_spending():
    """分析不同会员等级的消费情况"""
    pipeline = [
        # 1. 只关联已完成的订单
        {
            "$match": {
                "status": "completed"
            }
        },
        
        # 2. 关联用户信息,获取会员等级
        {
            "$lookup": {
                "from": "users",
                "localField": "user_id",
                "foreignField": "_id",
                "as": "user"
            }
        },
        
        # 3. 展开用户数组
        {
            "$unwind": "$user"
        },
        
        # 4. 按会员等级分组统计
        {
            "$group": {
                "_id": "$user.tier",
                "user_count": {"$sum": 1},
                "total_spent": {"$sum": "$total_amount"},
                "avg_spent": {"$avg": "$total_amount"},
                "max_order": {"$max": "$total_amount"},
                "min_order": {"$min": "$total_amount"}
            }
        },
        
        # 5. 按总消费金额排序
        {
            "$sort": {"total_spent": -1}
        }
    ]
    
    results = list(db.orders.aggregate(pipeline))
    
    print("=== 会员消费分析 ===")
    for r in results:
        print(f"等级: {r['_id']}")
        print(f"  用户数: {r['user_count']}")
        print(f"  总消费: ¥{r['total_spent']:.2f}")
        print(f"  平均消费: ¥{r['avg_spent']:.2f}")
        print(f"  最高单笔: ¥{r['max_order']:.2f}")
        print()
    
    return results

4.3 案例2:商品销售排行

需求:统计最近30天销量最高的商品,包括销售数量和销售额。

python 复制代码
def get_top_products(days=30, limit=5):
    """获取热销商品排行"""
    
    cutoff_date = datetime.now() - timedelta(days=days)
    
    pipeline = [
        # 1. 只统计最近完成的订单
        {
            "$match": {
                "status": "completed",
                "created_at": {"$gte": cutoff_date}
            }
        },
        
        # 2. 展开商品数组
        {
            "$unwind": "$items"
        },
        
        # 3. 按商品分组统计
        {
            "$group": {
                "_id": "$items.product_id",
                "product_name": {"$first": "$items.name"},
                "total_quantity": {"$sum": "$items.qty"},
                "total_sales": {
                    "$sum": {"$multiply": ["$items.price", "$items.qty"]}
                },
                "order_count": {"$sum": 1}
            }
        },
        
        # 4. 关联商品详情(可选)
        {
            "$lookup": {
                "from": "products",
                "localField": "_id",
                "foreignField": "_id",
                "as": "product_info"
            }
        },
        
        # 5. 展开商品信息
        {
            "$unwind": {
                "path": "$product_info",
                "preserveNullAndEmptyArrays": True
            }
        },
        
        # 6. 添加商品分类信息
        {
            "$addFields": {
                "category": "$product_info.category"
            }
        },
        
        # 7. 按销量排序
        {
            "$sort": {"total_quantity": -1}
        },
        
        # 8. 取前N名
        {
            "$limit": limit
        },
        
        # 9. 重塑输出文档
        {
            "$project": {
                "_id": 0,
                "product_id": "$_id",
                "product_name": 1,
                "category": 1,
                "total_quantity": 1,
                "total_sales": 1,
                "order_count": 1,
                "avg_price_per_order": {
                    "$divide": ["$total_sales", "$order_count"]
                }
            }
        }
    ]
    
    results = list(db.orders.aggregate(pipeline))
    
    print(f"=== 近{days}天热销商品TOP{limit} ===")
    for i, r in enumerate(results, 1):
        print(f"{i}. {r['product_name']} ({r.get('category', '未分类')})")
        print(f"   销量: {r['total_quantity']}件, 销售额: ¥{r['total_sales']:.2f}")
        print(f"   订单数: {r['order_count']}, 平均客单价: ¥{r['avg_price_per_order']:.2f}")
        print()
    
    return results

4.4 案例3:客户RFM分析

需求:基于最近购买时间(Recency)、购买频率(Frequency)、消费金额(Monetary)对客户进行RFM分析。

python 复制代码
def rfm_analysis():
    """RFM客户价值分析"""
    
    now = datetime.now()
    
    pipeline = [
        # 1. 只统计已完成的订单
        {
            "$match": {"status": "completed"}
        },
        
        # 2. 按用户分组,计算RFM指标
        {
            "$group": {
                "_id": "$user_id",
                "last_order_date": {"$max": "$created_at"},
                "order_count": {"$sum": 1},
                "total_spent": {"$sum": "$total_amount"}
            }
        },
        
        # 3. 计算R、F、M得分
        {
            "$addFields": {
                "recency_days": {
                    "$floor": {
                        "$divide": [
                            {"$subtract": [now, "$last_order_date"]},
                            1000 * 60 * 60 * 24  # 转换为天数
                        ]
                    }
                },
                "frequency": "$order_count",
                "monetary": "$total_spent"
            }
        },
        
        # 4. 分箱评分(简单示例)
        {
            "$addFields": {
                "r_score": {
                    "$switch": {
                        "branches": [
                            {"case": {"$lte": ["$recency_days", 7]}, "then": 5},
                            {"case": {"$lte": ["$recency_days", 30]}, "then": 4},
                            {"case": {"$lte": ["$recency_days", 90]}, "then": 3},
                            {"case": {"$lte": ["$recency_days", 180]}, "then": 2}
                        ],
                        "default": 1
                    }
                },
                "f_score": {
                    "$switch": {
                        "branches": [
                            {"case": {"$gte": ["$order_count", 10]}, "then": 5},
                            {"case": {"$gte": ["$order_count", 5]}, "then": 4},
                            {"case": {"$gte": ["$order_count", 3]}, "then": 3},
                            {"case": {"$gte": ["$order_count", 2]}, "then": 2}
                        ],
                        "default": 1
                    }
                },
                "m_score": {
                    "$switch": {
                        "branches": [
                            {"case": {"$gte": ["$total_spent", 5000]}, "then": 5},
                            {"case": {"$gte": ["$total_spent", 2000]}, "then": 4},
                            {"case": {"$gte": ["$total_spent", 1000]}, "then": 3},
                            {"case": {"$gte": ["$total_spent", 500]}, "then": 2}
                        ],
                        "default": 1
                    }
                }
            }
        },
        
        # 5. 计算总分并分类
        {
            "$addFields": {
                "rfm_score": {
                    "$concat": [
                        {"$toString": "$r_score"},
                        {"$toString": "$f_score"},
                        {"$toString": "$m_score"}
                    ]
                },
                "total_score": {
                    "$add": ["$r_score", "$f_score", "$m_score"]
                }
            }
        },
        
        # 6. 客户分类
        {
            "$addFields": {
                "customer_segment": {
                    "$switch": {
                        "branches": [
                            {"case": {"$gte": ["$total_score", 13]}, "then": "重要价值客户"},
                            {"case": {"$gte": ["$total_score", 10]}, "then": "重要发展客户"},
                            {"case": {"$gte": ["$total_score", 7]}, "then": "一般价值客户"}
                        ],
                        "default": "低价值客户"
                    }
                }
            }
        },
        
        # 7. 按总分排序
        {
            "$sort": {"total_score": -1}
        },
        
        # 8. 关联用户详情
        {
            "$lookup": {
                "from": "users",
                "localField": "_id",
                "foreignField": "_id",
                "as": "user"
            }
        },
        
        # 9. 展开用户信息
        {
            "$unwind": "$user"
        },
        
        # 10. 输出结果
        {
            "$project": {
                "_id": 0,
                "user_id": "$_id",
                "user_name": "$user.name",
                "email": "$user.email",
                "recency_days": 1,
                "order_count": 1,
                "total_spent": 1,
                "rfm_score": 1,
                "customer_segment": 1
            }
        }
    ]
    
    results = list(db.orders.aggregate(pipeline))
    
    print("=== RFM客户价值分析 ===")
    for r in results[:10]:  # 只显示前10条
        print(f"用户: {r['user_name']} ({r['email']})")
        print(f"  最近购买: {r['recency_days']}天前, 订单数: {r['order_count']}, 总消费: ¥{r['total_spent']:.2f}")
        print(f"  RFM得分: {r['rfm_score']}, 客户类型: {r['customer_segment']}")
        print()
    
    return results

4.5 运行完整示例

python 复制代码
def run_all_analyses():
    """运行所有分析示例"""
    
    # 1. 用户消费分析
    analyze_user_spending()
    
    print("\n" + "="*60 + "\n")
    
    # 2. 热销商品排行
    get_top_products(days=30, limit=5)
    
    print("\n" + "="*60 + "\n")
    
    # 3. RFM分析
    rfm_analysis()


if __name__ == "__main__":
    run_all_analyses()

5. 聚合管道性能优化

5.1 优化原则

根据 MongoDB 官方建议和实际经验,聚合管道性能优化应遵循以下原则:
性能优化原则
尽早过滤
减少数据
善用索引
控制内存
match 放在最前 project 缩减字段
unwind 前先过滤 为match/$sort建索引
遵循ESR原则
启用 allowDiskUse
避免内存排序

5.2 具体优化策略

5.2.1 尽早使用 $match

$match 阶段放在管道的最前面,这样可以减少后续阶段需要处理的数据量。

python 复制代码
# ❌ 低效:先展开再过滤
pipeline = [
    {"$unwind": "$items"},
    {"$match": {"items.price": {"$gt": 1000}}}
]

# ✅ 高效:先过滤再展开
pipeline = [
    {"$match": {"total_amount": {"$gt": 1000}}},
    {"$unwind": "$items"}
]
5.2.2 使用 $project 减少数据量

只保留必要的字段,可以显著降低内存和网络开销。

python 复制代码
pipeline = [
    {"$match": {"status": "completed"}},
    # 尽早移除不需要的大字段
    {"$project": {"_id": 0, "order_no": 1, "total_amount": 1, "items": 1}},
    # 后续操作...
]
5.2.3 索引设计策略
  • ESR原则 :对于复合索引,遵循 E quality(等值查询)、S ort(排序)、Range(范围查询)的字段顺序
  • 为 $lookup 建立索引 :确保 foreignField 上有索引
  • 使用 explain() 分析:检查索引使用情况
python 复制代码
# 创建复合索引
db.orders.create_index([("status", 1), ("created_at", -1)])

# 分析查询计划
explain_result = db.orders.aggregate(pipeline, explain=True)
print(explain_result)
5.2.4 处理大数据集

当管道处理的数据量超过 100MB 内存限制时,需要启用 allowDiskUse 选项。

python 复制代码
# 允许使用磁盘处理大数据
results = db.orders.aggregate(pipeline, allowDiskUse=True)

5.3 常见性能陷阱

陷阱 后果 解决方案
$match 放在后面 大量无用数据流经管道 $match 移到最前面
缺少必要索引 全表扫描,性能低下 分析查询,创建合适索引
$unwind 后数据暴增 内存压力大 展开前先过滤,考虑是否需要展开
内存中排序大数据集 排序超时或失败 创建索引支持排序,启用 allowDiskUse
多个 $lookup 串联 性能急剧下降 合并关联条件,使用子管道

6. 总结

MongoDB 聚合管道是一个强大而灵活的数据处理框架,它通过多个阶段的组合,能够完成从简单过滤到复杂多表关联、统计分析等各种查询需求。掌握聚合管道,意味着你可以直接在数据库层面完成复杂的数据处理,无需将大量数据拉到应用层计算。

关键要点回顾

  1. 管道思维:将复杂查询分解为多个阶段,每个阶段完成一个明确的任务
  2. 阶段顺序$match$project 尽可能提前,减少后续阶段数据量
  3. 善用索引 :为 $match$sort$lookup 的关联字段创建索引
  4. 内存意识 :了解 100MB 内存限制,大数据量时启用 allowDiskUse
  5. 工具辅助 :使用 explain() 分析查询计划,持续优化

通过本文的实战案例,你应该已经掌握了 MongoDB 聚合管道的核心用法和优化技巧。在实际项目中,建议结合具体业务需求和数据特点,灵活组合各个阶段,构建出既满足功能需求又具备良好性能的聚合查询。


附录:运行环境要求

bash 复制代码
# 安装依赖
pip install pymongo==4.5.0

# 启动 MongoDB(Docker方式)
docker run -d --name mongodb -p 27017:27017 mongo:6.0

# 进入 MongoDB Shell
docker exec -it mongodb mongosh
相关推荐
好记忆不如烂笔头abc1 小时前
不同 Oracle 版本的客户端/服务器互操作性支持矩阵
服务器·oracle·矩阵
Volunteer Technology1 小时前
Oracle数据DML语句和DQL语句
oracle
勇往直前plus3 小时前
从文件到屏幕:Python/java 字符编码、解码、文本处理的底层逻辑解析
java·开发语言·python
无限进步_4 小时前
面试题 02.04. 分割链表 - 题解与详细分析
c语言·开发语言·数据结构·git·链表·github·visual studio
zh_xuan4 小时前
kotlin Flow的用法
android·开发语言·kotlin·协程·flow
Mr YiRan7 小时前
C++面向对象继承与操作符重载
开发语言·c++·算法
z玉无心10 小时前
Redis
数据库·redis·oracle
一只鹿鹿鹿10 小时前
智慧水利一体化建设方案
大数据·运维·开发语言·数据库·物联网
_codemonster10 小时前
数据库字符集编码问题
android·数据库·oracle