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

使用PyMongo更新MongoDB文档中Discord邀请使用次数

解决MongoDB中Discord邀请使用次数自增的问题

问题根源

你的代码存在两个关键错误:

  • 数组元素定位失败:update_one的filter仅匹配了_id,MongoDB的$操作符无法确定要更新invites数组中的哪一个元素,必须在filter中添加对目标邀请码的匹配条件。
  • 更新路径错误:你用当前的使用次数值(比如0)作为数组索引拼接路径,而实际上使用次数是目标数组的第一个元素(索引固定为0),正确路径应该指向该固定位置。

修正后的代码

filter = {'_id': guild.id}
invite_pool = await guild.invites()
query = await db.guilds.find_one(filter)
tracked_invites = query['invites']

for invite in invite_pool:
    # 构建邀请码到跟踪数据的映射,避免嵌套循环(可选优化)
    tracked_map = {next(iter(item)): item[next(iter(item))] for item in tracked_invites}
    
    if invite.code in tracked_map:
        tracked_uses = tracked_map[invite.code][0]
        if tracked_uses != invite.uses:
            # 构建包含数组元素匹配的filter,定位到目标邀请码所在的数组项
            update_filter = {
                '_id': guild.id,
                'invites': {'$elemMatch': {invite.code: {'$exists': True}}}
            }
            # 正确的更新路径:指向invites数组中匹配项的邀请码对应的数组第一个元素
            await db.guilds.update_one(
                update_filter,
                {'$inc': {f'invites.$.{invite.code}.0': 1}}
            )
            return tracked_map[invite.code][1]

关键修正点说明

  1. 精准定位数组元素:使用$elemMatch在filter中匹配invites数组中包含目标邀请码的元素,确保$操作符能正确指向要更新的数组项。
  2. 固定索引路径:直接使用0作为数组索引,因为使用次数始终是邀请码对应数组的第一个元素,无需用当前数值拼接路径。
  3. 循环优化:将tracked_invites转换为字典映射,把嵌套循环改为单次查找,提升代码效率。

可选结构优化建议

当前invites数组的结构(每个元素是单键对象)不利于高效查询和更新,建议将其改为对象结构:

"invites": {
  "UrxbKHJV": [0,"1118711272054198322","2025-03-01 15:18:55.838000+00:00"],
  "bVnjb7ser9": [0,"1118711272054198322","2025-03-01 16:27:03.759000+00:00"]
}

这样更新操作会更简洁,无需处理数组定位:

await db.guilds.update_one(
    {'_id': guild.id},
    {'$inc': {f'invites.{invite.code}.0': 1}}
)

内容的提问来源于stack exchange,提问作者user29836029

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 01:37:08