Skip to content

Instantly share code, notes, and snippets.

@renbaoshuo
Created July 20, 2026 06:17
Show Gist options
  • Select an option

  • Save renbaoshuo/73cc063f752d6727705f05f3f06a1288 to your computer and use it in GitHub Desktop.

Select an option

Save renbaoshuo/73cc063f752d6727705f05f3f06a1288 to your computer and use it in GitHub Desktop.

HydroOJ 删除比赛

⚠️注意 ‼️本操作不可逆!!!请做好备份后再执行,执行前请务必确认好操作目标!!!!

先使用 hydrooj backup 备份数据库。

使用 hydrooj db 命令进入 mongosh,然后执行下面的命令定义比赛删除函数:

// 定义一个删除比赛的函数,参数为 domainId(域ID)和 tid(比赛ID)
function deleteContest(domainId, tid) {
    // 如果 tid 传的是字符串,转成 ObjectId;已经是 ObjectId 就保持原样
    tid = (typeof tid === "string") ? ObjectId(tid) : tid;
    // 查出该比赛下所有「答疑」文档(docType=31)的 _id 列表
    // 先 toArray() 物化成普通对象再 map,避免游标代理的循环引用问题
    const cids = db.document.find({ domainId, docType: 31, parentType: 30, parentId: tid }).toArray().map(d => d._id);
    // 查出该比赛下所有「打印任务」文档(docType=32)的 _id 列表
    const pids = db.document.find({ domainId, docType: 32, parentType: 30, parentId: tid }).toArray().map(d => d._id);

    // 删除比赛文档本身(docType=30, docId=tid)
    db.document.deleteMany({ domainId, docType: 30, docId: tid });
    // 删除该比赛的参赛状态(document.status 集合,docType=30)
    db["document.status"].deleteMany({ domainId, docType: 30, docId: tid });
    // 删除挂在比赛下的讨论(parentType=30, parentId=tid)
    db.document.deleteMany({ domainId, parentType: 30, parentId: tid });
    // 如果有答疑,删除这些答疑文档
    if (cids.length) {
        db.document.deleteMany({ _id: { $in: cids } });
        // 一并删除这些答疑对应的状态文档
        db["document.status"].deleteMany({ domainId, docType: 31, docId: { $in: cids } });
    }
    // 如果有打印任务,删除这些打印文档
    if (pids.length) {
        db.document.deleteMany({ _id: { $in: pids } });
        // 一并删除这些打印任务对应的状态文档
        db["document.status"].deleteMany({ domainId, docType: 32, docId: { $in: pids } });
    }
    // 删除该比赛的气球记录(contest.balloon 集合)
    db["contest.balloon"].deleteMany({ domainId, tid });
    // 删除该比赛的定时隐藏任务(schedule 集合)
    db.schedule.deleteMany({ type: "schedule", subType: "contest", domainId, tid });
    // 比赛内提交记录【保留】,仅解除与比赛的关联(unset contest 字段)
    db.record.updateMany({ domainId, contest: tid }, { $unset: { contest: "" } });
    // 返回完成提示
    return "done: contest " + tid;
}

之后调用函数来删除比赛:

// 调用函数,删除指定域下指定 ID 的比赛(示例参数,请替换为真实值)
deleteContest("system", "contestId");

说明几个字段含义,便于核对:

  • docType:30=比赛,31=答疑,32=打印任务(定义在 document.ts)。
  • parentType: 30, parentId: tid:表示「挂在 tid 这场比赛下的子文档」(讨论/答疑/打印都用这个关联)。
  • document.status 是独立集合(collStatus),所以比赛、答疑、打印的状态都单独再删一遍。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment