Mongoengine聚合查询返回空列表问题排查(内嵌文档场景)
解决Mongoengine聚合返回空列表的问题
场景回顾
你有一个包含内嵌数组的MongoDB文档,示例结构如下:
{ "make": "Toyota", "color": "blue", "tires": [ { "make": "Mishlen", "size": 185 }, { "make": "Mishlen", "size": 210 } ] }
你的需求是执行聚合查询,返回完整文档的同时,仅保留tires数组中size大于200的元素。
原生MongoDB查询正常运行
你编写的MongoDB原生聚合查询可以正确实现需求:
db.cars.aggregate([ { $match: { $and: [{ "tires.size": { $gt: 200 } }] } }, { $addFields: { "tires": { $filter: { input: '$tires', as: 'tires', cond: { $gt: ['$$tires.size', 200] } } } } }, { $limit: 100 }, { $skip: 0 } ])
Mongoengine中遇到的问题
但在使用Mongoengine执行类似聚合管道时,始终返回空列表:
pipeline = [ { "$match": {"$and": [{"tires.size": {"$gt": 200}}]} }, { "$addFields": { "tires": { "$filter": { "input": "$tires", "as": "tires", "cond": {"$and": [{"$gt": ["$$tires.size", 200]}]} } } } } ] self.obj_type.objects.aggregate(*pipeline)
问题原因与解决方法
经过排查,问题的核心原因是在Python中误将数字以字符串而非整数传入。MongoDB对数据类型的匹配是严格的:如果你的文档中tires.size存储的是整数类型,而查询条件里用了字符串形式的数字(比如"200"),就会导致没有任何文档能匹配到,最终返回空列表。
修正起来很简单:确保聚合管道中的数字条件使用整数类型(不要加引号)。另外,你的管道里还有个小冗余——$match和$filter中的$and其实没必要,因为只包含单个条件,直接简化写法即可。修正后的代码如下:
pipeline = [ { "$match": {"tires.size": {"$gt": 200}} }, { "$addFields": { "tires": { "$filter": { "input": "$tires", "as": "tires", "cond": {"$gt": ["$$tires.size", 200]} } } } } ] self.obj_type.objects.aggregate(*pipeline)
内容的提问来源于stack exchange,提问作者Michael Royf
相关产品推荐
相关产品推荐

