pymongo如何查询同一文档内nodeId与node.id字段匹配的数据?
MongoDB同文档嵌套数组字段匹配查询实现方案
要实现同文档内字段的对比查询,需要使用MongoDB的$expr运算符,针对你嵌套两层数组(players、pings)的结构,两种实现方式如下:
方式1:仅过滤符合条件的文档(不对返回内容做过滤)
仅判断文档中是否存在至少一个pings.nodeId等于同文档match.node.id的记录,符合条件就返回完整文档:
query = { "$and": [ {"match.season": "1"}, # 注意原文档season为字符串类型,保持类型匹配 {"match.players": {"$exists": True}}, {"$expr": { "$gt": [ {"$size": { "$filter": { "input": { "$reduce": { "input": "$match.players", "initialValue": [], "in": {"$concatArrays": ["$$value", "$$this.pings"]} } }, "as": "ping", "cond": {"$eq": ["$$ping.nodeId", "$match.node.id"]} } }}, 0 ] }} ] } projection = { "match.node.id": 1, "match.players.pings": 1 } result = db_collection.find_one(query, projection)
方式2:过滤返回结果,仅保留符合条件的ping记录
如果需要返回结果自动剔除不符合条件的pings、以及没有符合条件pings的玩家,使用聚合管道实现:
pipeline = [ # 先过滤基础符合条件的文档,减少后续计算量 {"$match": { "match.season": "1", "match.players": {"$exists": True} }}, # 过滤每个玩家的pings,仅保留nodeId匹配的记录 {"$addFields": { "match.players": { "$map": { "input": "$match.players", "as": "player", "in": { "$mergeObjects": [ "$$player", {"pings": { "$filter": { "input": "$$player.pings", "as": "ping", "cond": {"$eq": ["$$ping.nodeId", "$match.node.id"]} } }} ] } } } }}, # 可选:过滤掉pings为空的玩家 {"$addFields": { "match.players": { "$filter": { "input": "$match.players", "as": "player", "cond": {"$gt": [{"$size": "$$player.pings"}, 0]} } } }}, # 可选:过滤掉没有符合条件玩家的文档 {"$match": { "$expr": {"$gt": [{"$size": "$match.players"}, 0]} }}, # 投影需要的字段 {"$project": { "match.node.id": 1, "match.players.userId": 1, "match.players.pings": 1 }} ] result_list = list(db_collection.aggregate(pipeline)) result = result_list[0] if result_list else None
注意事项
- 优先使用方式1,性能更高,仅当需要对返回内容做裁剪时使用方式2
- 注意字段类型匹配,避免因为字符串和数字类型不匹配导致查询无结果
内容的提问来源于stack exchange,提问作者idontknowmuch
相关产品推荐
相关产品推荐

