You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MongoDB(Python驱动)如何按文档内字段分组统计文档数量

Python操作MongoDB实现租车车辆聚合计数

场景说明

MongoDB实例中存储了数千条虚拟租车公司的车辆档案,单条文档结构如下:

{
    "model": "Honda Civic",
    "license_plate": "ABC-1234",
    "attributes":
        {
            "rented": "YES",
            ...其他业务字段...
        }
}

当前已实现逻辑为:先通过distinct("model")拉取所有车型,遍历每个车型单独构建聚合管道,匹配对应车型后投影出model、license_plate、attributes.rented字段逐行打印,运行结果符合预期,现有代码如下:

mydatabase = client.CARS_DB
mycollection = mydatabase.RENTAL_LOT_A

listOfRules = mycollection.distinct("model")

for rule in listOfRules:
    match_variable = {
      "$match": { 'model': rule }
    }
    project_variable = {
      "$project": {
        '_id': 0,
        'model': 1,
        'license_plate': 1,
        'attributes.rented': 1
      }
    }
    pipeline = [
      match_variable,
      project_variable
    ]
    results = mycollection.aggregate(pipeline)
    for r in results:
      print(r)
      print("- - - - - - - - - - - - - - - - -")

代码运行输出示例:

{'model': 'Honda Civic', 'license_plate': 'ABC-1234', 'attributes': {'rented': 'YES'}}
- - - - - - - - - - - - - - - - -
{'model': 'Toyota Camry', 'license_plate': 'ABC-5678', 'attributes': {'rented': 'YES'}}
- - - - - - - - - - - - - - - - -
{'model': 'Honda Civic', 'license_plate': 'DEF-1001',  'attributes': {'rented': 'no'}}
- - - - - - - - - - - - - - - - -

待实现需求

现有逻辑仅能逐行返回单条车辆明细,无法满足统计需求,无需返回license_plate字段,需要实现两类统计效果:

  • 仅按model字段分组,统计每个车型对应的车辆总数量
  • 按model和attributes.rented字段联合分组,统计各车型下已出租、可租状态的车辆数量

此前尝试过Python端字典遍历统计、db.collection.countDocuments()等方案均未达到预期,可接受修改现有聚合管道或编写全新实现的方案。


实现方案

无需提前拉取全量车型再循环发起聚合请求,直接通过聚合管道的$group阶段在数据库侧完成统计即可,执行效率远高于循环请求的实现。

按车型统计总车辆数

将$group的分组键设置为$model,通过$sum累加器完成计数,参考代码:

pipeline = [
    {
        "$group": {
            "_id": "$model",
            "total_count": {"$sum": 1}
        }
    },
    # 可选阶段:调整输出字段结构,将分组键重命名为model,隐藏默认_id字段
    {
        "$project": {
            "_id": 0,
            "model": "$_id",
            "total_count": 1
        }
    }
]

results = mycollection.aggregate(pipeline)
for res in results:
    print(res)

返回结果示例:

{'total_count': 2, 'model': 'Honda Civic'}
{'total_count': 1, 'model': 'Toyota Camry'}

按车型+出租状态联合统计

将$group的分组键设置为包含model和attributes.rented的复合键即可,参考代码:

pipeline = [
    {
        "$group": {
            "_id": {
                "model": "$model",
                "rented_status": "$attributes.rented"
            },
            "count": {"$sum": 1}
        }
    },
    # 可选阶段:展平分组键结构,优化输出可读性
    {
        "$project": {
            "_id": 0,
            "model": "$_id.model",
            "rented_status": "$_id.rented_status",
            "count": 1
        }
    }
]

results = mycollection.aggregate(pipeline)
for res in results:
    print(res)

返回结果示例:

{'count': 1, 'model': 'Honda Civic', 'rented_status': 'YES'}
{'count': 1, 'model': 'Toyota Camry', 'rented_status': 'YES'}
{'count': 1, 'model': 'Honda Civic', 'rented_status': 'no'}

注意:当前示例数据中attributes.rented字段值同时存在大写YES、小写no的格式差异,如果需要做状态归一化统计,可在$group阶段前增加$addFields阶段,通过$toLower操作符将状态值统一转为小写后再分组,避免同状态因大小写差异被拆分为多个分组。


内容的提问来源于stack exchange,提问作者Pete

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 01:33:19