MongoDB/pymongo如何查询未知键任意长度集合是否存在指定字符串
MongoDB/pymongo 匹配未知键对象的指定值实现方案
$elemMatch 是数组专用的查询操作符,不适用对象键值匹配场景,你可以根据自己的MongoDB版本选下面的方案:
方案1:通用转换查询(支持MongoDB 3.4.4及以上所有版本,无需提前建索引)
核心思路是用$objectToArray运算符把键名未知的对象,转换成{k: 键名, v: 键值}结构的数组,再过滤数组里是否存在值为foobar的元素。
MongoDB原生查询写法:// 替换yourCollection为你的实际集合名 db.yourCollection.find({ $expr: { $gt: [ { $size: { $filter: { input: { $objectToArray: "$myJsonObject" }, cond: { $eq: ["$$this.v", "foobar"] } } } }, 0 ] } })对应pymongo写法:
from pymongo import MongoClient client = MongoClient("mongodb://localhost:27017/") col = client["你的数据库名"]["你的集合名"] query = { "$expr": { "$gt": [ { "$size": { "$filter": { "input": {"$objectToArray": "$myJsonObject"}, "cond": {"$eq": ["$$this.v", "foobar"]} } } }, 0 ] } } # 只要存在1条匹配结果就返回True,性能更好 has_target = col.count_documents(query, limit=1) > 0 print(has_target)方案2:通配符索引查询(支持MongoDB 4.2及以上版本,适合高频查询、数据量大的场景)
如果这个查询是高频操作,可以先给目标字段建通配符索引,查询时不需要做聚合转换,性能更高:// 先建通配符索引,myJsonObject下所有层级的键都会被索引 db.yourCollection.createIndex({"myJsonObject.$**": 1}) // 直接用通配符键查询即可 db.yourCollection.find({"myJsonObject.$**": "foobar"})pymongo中直接把上述查询条件传入
find或count_documents即可,语法完全一致。
补充说明:如果你的嵌套对象里存在更深层的子对象、数组类型值,上述两种方法默认会递归匹配所有层级的值;如果只需要匹配第一层键对应的字符串值,在方案1的
cond里加一个类型判断{$eq: [{$type: "$$this.v"}, "string"]}即可。
内容的提问来源于stack exchange,提问作者lostcat-sendhelp
相关产品推荐
相关产品推荐

