如何使用PyMongo查询两个指定日期的数据
MongoDB匹配指定日期文档的查询问题解决
一、当前查询结果异常的原因
你的查询存在两个核心问题:
- 重复键覆盖:在同一个查询对象中重复声明
TIMESTAMP键,后写的条件会直接覆盖前一个,实际只会执行{'$lt': past_end, '$gte': past_start}这部分逻辑,导致结果遗漏。 - 逻辑运算符错误:你要获取的是今天或昨天的文档,应该用
$or而非$and——$and要求文档同时满足两个时间区间,这显然不可能(一个文档的时间无法同时属于两天)。
二、修复后的查询代码
修正逻辑与语法后的代码如下,同时简化了日期对象的构造(无需反复转字符串再转回):
def delta(timeframe): from datetime import datetime, timedelta import pandas as pd search_column = "TIMESTAMP" if timeframe == "1": today = datetime.today() past = today - timedelta(days=1) # 直接构造当日0点和次日0点的datetime对象 today_start = datetime(today.year, today.month, today.day) today_end = today_start + timedelta(days=1) past_start = datetime(past.year, past.month, past.day) past_end = past_start + timedelta(days=1) # 用$or匹配今天或昨天的文档 query = { "$or": [ {search_column: {"$gte": today_start, "$lt": today_end}}, {search_column: {"$gte": past_start, "$lt": past_end}} ] } a = collection.find(query) list_cur = list(a) df = pd.DataFrame(list_cur) print(df)
三、无需设置起止时间的简化查询方案
如果你想直接匹配指定日期(忽略时间部分),可以用$expr结合$dateToString提取日期字符串进行匹配,示例如下:
def delta(timeframe): from datetime import datetime, timedelta import pandas as pd search_column = "TIMESTAMP" if timeframe == "1": today = datetime.today() past = today - timedelta(days=1) # 生成匹配用的日期字符串 today_str = today.strftime("%Y-%m-%d") past_str = past.strftime("%Y-%m-%d") query = { "$expr": { "$in": [ {"$dateToString": {"format": "%Y-%m-%d", "date": f"${search_column}"}}, [today_str, past_str] ] } } a = collection.find(query) list_cur = list(a) df = pd.DataFrame(list_cur) print(df)
注意:这种方式无法利用
TIMESTAMP字段的索引,数据量大时性能会低于起止时间的方案,优先推荐第一种写法。
额外提示
数据库中的TIMESTAMP是UTC时区的ISODate格式(2022-08-21T08:02:21.000+00:00),如果你的本地时间与UTC存在偏差,建议用datetime.utcnow()替代datetime.today()构造查询时间,避免时区差异导致的数据漏查。
内容的提问来源于stack exchange,提问作者Ethyl
相关产品推荐
相关产品推荐

