MongoEngine中能否在同一查询中结合contains与exists?
在MongoEngine中结合键匹配与存在性查询MapField
首先明确:可以实现,但你当前的写法完全错误——MongoEngine的contains操作符是针对数组或字符串类型的字段值,而非MapField的键;而exists是检查特定精确键是否存在,无法用来匹配键的前缀或包含关系。
问题根源
你的代码中playtime__{"2024-01"}__exists和playtime__{"2024-01"}__contains是逻辑错误:"2024-01"并不是文档中实际存在的键(实际键是完整的时间字符串如"2024-01-03 4:00:00"),所以MongoDB无法找到对应的键,自然返回空结果。
正确解决方案
要筛选MapField(对应MongoDB中的对象类型)中存在包含特定字符串的键的文档,需要针对MapField的键集合进行正则匹配,MongoEngine支持通过__keys后缀访问键集合,结合__regex实现模糊匹配:
from mongoengine import Q from typing import List entries: List[GameDoc] = [] # 匹配playtime中所有包含"2024-01"的键 query = Q(playtime__keys__regex=r"2024-01") entries.extend(GameDoc.objects(query))
扩展场景:同时满足多个键条件
如果需要同时筛选“存在包含"2024-01"的键”和“存在某个精确键”,可以用Q对象组合查询:
dt_str = "2024-01-03 4:00:00" # 同时满足:有包含2024-01的键,且精确键dt_str存在 query = Q(playtime__keys__regex=r"2024-01") & Q(**{f'playtime__{dt_str}__exists': True}) entries = GameDoc.objects(query)
原理说明
playtime__keys:MongoEngine会将其解析为针对MapField所有键的查询__regex=r"2024-01":用正则表达式匹配键中包含指定字符串的条目,等价于MongoDB原生的键匹配逻辑
内容的提问来源于stack exchange,提问作者linkey apiacess
相关产品推荐
相关产品推荐

