You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 23:54:03