Jupyter Notebook中PyMongo投影查询MongoDB报InvalidBSON错误
核心问题根因定位
最终报错InvalidBSON: year -1 is out of range不属于查询语法错误,所有你在终端验证过可正常运行的查询写法逻辑都是正确的,问题根源来自Jupyter运行环境的PyMongo/BSON组件版本错位,而非MongoDB服务端或查询规则本身。
触发场景的逻辑解释
- 同一份代码终端可跑、Jupyter报错:说明你当前Jupyter内核绑定的Python解释器,和终端执行脚本调用的解释器,安装的依赖版本不匹配
- 不带投影的简单查询可跑、带
$elemMatch/位置运算符的投影查询就报错:带投影的查询会触发PyMongo的_decode_all_selective选择性解码分支,版本不匹配的BSON组件在解码携带异常偏移时间值的字段时,会直接抛出年数越界的解码错误;全字段查询走全量解码的兼容逻辑,反而绕过了这个分支的bug。
可落地的排查与修复步骤
- 对齐依赖版本
先在Jupyter单元格执行以下代码打印当前环境的依赖版本,再在终端执行完全相同的打印语句,对比两边的版本号:
将Jupyter环境内的import pymongo import bson print("Jupyter环境pymongo版本:", pymongo.__version__) print("Jupyter环境bson版本:", bson.__version__)pymongo版本调整为和终端完全一致的版本即可解决解码报错。注意:不要单独从PyPI安装独立的
bson包,该包和PyMongo自带的内置BSON模块会产生版本冲突,是触发这类问题的高频诱因,正确做法是仅安装pymongo,依赖的BSON组件会随PyMongo自动匹配版本。 - 临时业务逻辑绕过
如果暂时无法调整环境依赖,可以把数组筛选的逻辑从查询投影阶段迁移到内存中处理,直接规避选择性解码的代码分支:# 仅做文档级筛选,不设置数组投影参数 query = {"custom_field.app_custom_field_id": 1871} df = pd.DataFrame(mycol.find(query, {"_id": 0})) # 在DataFrame中对每行的custom_field数组做匹配过滤 df["custom_field"] = df["custom_field"].apply( lambda item_list: [item for item in item_list if item.get("app_custom_field_id") == 1871] )
内容的提问来源于stack exchange,提问作者Reche.Lab
相关产品推荐
相关产品推荐

