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

MongoDB聚合管道构建问题:按时间范围匹配并统计文档

解决MongoDB字符串日期匹配及统计问题

你遇到的核心问题是select_time是字符串类型,没法直接和Python的datetime对象做比较——MongoDB只会把字符串按字典序对比,完全不是你要的时间逻辑。给你两种可行的解决方案,直接改你的聚合管道就行:

方法一:先转换日期字段,再匹配统计

先通过$addFields新增一个转换后的日期类型字段,再基于这个字段做时间范围匹配,最后按location_id统计:

import datetime
from pymongo import MongoClient

client = MongoClient()
db = client.your_database
collection = db.your_collection

# 计算时间范围
last_hour = datetime.datetime.now() - datetime.timedelta(minutes=60)
now = datetime.datetime.now()

pipeline = [
    # 把字符串格式的select_time转成MongoDB日期类型
    {
        "$addFields": {
            "select_time_date": {
                "$dateFromString": {
                    "dateString": "$select_time",
                    "format": "%m-%d-%Y %H:%M:%S"  # 严格对应你的日期格式
                }
            }
        }
    },
    # 匹配过去一小时内的文档
    {
        "$match": {
            "select_time_date": {
                "$gt": last_hour,
                "$lte": now
            }
        }
    },
    # 按location_id分组统计数量(可根据你的需求修改统计逻辑)
    {
        "$group": {
            "_id": "$location_id",
            "total_selections": {"$sum": 1}
        }
    }
]

# 执行聚合
result = list(collection.aggregate(pipeline))
print(result)

方法二:在匹配阶段直接转换(更简洁)

用$expr表达式在$match阶段直接转换字符串日期,省去新增字段的步骤:

# 时间范围计算同上
last_hour = datetime.datetime.now() - datetime.timedelta(minutes=60)
now = datetime.datetime.now()

pipeline = [
    {
        "$match": {
            "$expr": {
                "$and": [
                    # 转换select_time并判断是否大于last_hour
                    {"$gt": [
                        {"$dateFromString": {"dateString": "$select_time", "format": "%m-%d-%Y %H:%M:%S"}},
                        last_hour
                    ]},
                    # 转换select_time并判断是否小于等于now
                    {"$lte": [
                        {"$dateFromString": {"dateString": "$select_time", "format": "%m-%d-%Y %H:%M:%S"}},
                        now
                    ]}
                ]
            }
        }
    },
    # 统计阶段同上
    {
        "$group": {
            "_id": "$location_id",
            "total_selections": {"$sum": 1}
        }
    }
]

result = list(collection.aggregate(pipeline))

注意事项

  • 确保format参数和你的select_time格式完全一致:如果是12小时制(带AM/PM),需要把%H改成%I并加上%p(比如"%m-%d-%Y %I:%M:%S %p");
  • 如果有格式错误的select_time字符串,$dateFromString会返回null,这类文档会被自动过滤掉。如果需要保留或标记它们,可以在$match里加上"select_time": {"$ne": ""}或者后续处理null值;
  • Python的datetime对象会被MongoDB驱动自动转换成ISODate类型,不用手动转换。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 12:30:09