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

匹配ID批量更新MongoDB文档:向数组字段推送赛事成绩对象

问题描述

我在MongoDB中维护了一个F1车手集合,集合内文档包含id、driver_name、totla_points(注:此处为拼写错误)以及用于存储各赛事积分的results数组字段。通过网页表单提交单场赛事的完整结果,表单数据包含event_id、event_name,以及由多个含driver_id和对应积分的对象组成的positions数组。

需求:根据车手id与positions数组中对象的id匹配,批量更新集合中对应车手的文档,将该赛事的成绩(event_id、event_name、points)推送至其results数组中。后续还需更新车手的total_points字段(当前暂不处理)。

当前使用updateMany查询无法正确实现需求,请求修正代码。


现有代码

前端表单处理与提交代码

// 网页表单处理函数
function handleRaceResultSubmit(e) {
    e.preventDefault();

    let positions = [{id: null, points: 25}, {id: null, points: 18},{id: null, points: 15},{id: null, points: 12},{id: null, points: 10},
        {id: null, points: 8},{id: null, points: 6},{id: null, points: 4},{id: null, points: 2},{id: null, points: 1},
        {id: null, points: 0},{id: null, points: 0},{id: null, points: 0},{id: null, points: 0},{id: null, points: 0},
        {id: null, points: 0},{id: null, points: 0},{id: null, points: 0},{id: null, points: 0},{id: null, points: 0},];

    const eventID = parseInt(document.querySelector('#event-select').value);
    const eventName = document.querySelector('#event-select').textContent;
    const selectGroup = document.querySelectorAll('.select-group');

    selectGroup.forEach((driver, index) => {        
        positions[index].id = parseInt(driver.value);
    })

    const raceResult = {
        event_id: eventID,
        event_name: eventName,
        result: positions
    }

    updateDriverResults(raceResult);
}

// 向接口提交结果
const updateDriverResults = async (data) => {
    fetch('driver-points',
    {
        method: "POST",
        headers: {"Content-Type": "application/json"},
        body: JSON.stringify(data)
    }).then(res => {return res.json()})
    .then(data => console.log(data))
    .catch(error => console.log(error));
}

后端接口与Mongoose查询代码

// 后端接口及Mongoose查询
app.post('/driver-points', express.json(), (req, res) => {

    Drivers.updateMany({
        'id': { $in: [ req.body.result.id ] },
    },
    {
        $push: {'results': {
            'event_id': req.body.event_id,
            'event_name': req.body.event_name,
            'points': req.body.result.points
        }}
    })    
    .then((result) => {
        res.send(result);
    })
    .catch((error) => {
        console.log(error);
    })
})

Mongoose模型代码

// Mongoose模型
import { mongoose } from "mongoose";
const Schema = mongoose.Schema;

const driversSchema = new Schema({
    id: Number,
    driver_name: String,
    totla_points: Number,
    results: Array
});

const Drivers = mongoose.model('driver', driversSchema);

export { Drivers };

问题分析与修正方案

当前updateMany查询的核心问题:

  1. req.body.result是数组,req.body.result.id返回undefined,导致$in条件无效,无法匹配任何车手id
  2. updateMany无法为不同文档设置不同的更新值,所有匹配车手会被推送相同积分,不符合需求

正确实现需使用批量写入(bulkWrite),遍历positions数组为每个车手生成独立更新操作:

修正后的后端接口代码

app.post('/driver-points', express.json(), async (req, res) => {
    try {
        const { event_id, event_name, result: positions } = req.body;
        // 过滤id为null的无效条目
        const validPositions = positions.filter(pos => pos.id !== null);

        const bulkOps = validPositions.map(pos => ({
            updateOne: {
                filter: { id: pos.id },
                update: {
                    $push: {
                        results: {
                            event_id,
                            event_name,
                            points: pos.points
                        }
                        // 后续更新total_points时,添加以下代码:
                        // $inc: { total_points: pos.points }
                    }
                }
            }
        }));

        const result = await Drivers.bulkWrite(bulkOps);
        res.send(result);
    } catch (error) {
        console.error(error);
        res.status(500).send({ error: '更新失败' });
    }
})

额外优化建议

  1. 修正模型中totla_points的拼写错误为total_points,避免维护混淆
  2. 为results字段定义明确Schema结构,提升数据一致性:
const driversSchema = new Schema({
    id: Number,
    driver_name: String,
    total_points: Number, // 修正拼写错误
    results: [{
        event_id: Number,
        event_name: String,
        points: Number
    }]
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 02:14:51