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

MongoDB使用$switch分支判断子数组isPass状态更新索引问题

MongoDB findOneAndUpdate 中通过 $switch 实现数组元素状态判断逻辑

已定义的 Mongoose Schema

const mongoose = require("mongoose");
const uniqueValidator = require("mongoose-unique-validator");

const Schema = mongoose.Schema;

const stepsSchema = new Schema({
    oid: { type: String },
    wid:  { type: String },
    tid:  { type: String },
    flow: {type: Object},
    actionFlow: [[{id: {type:String}, isPass: {type: Boolean}}]],      // 类似输入状态管理的运行逻辑
    stepHistory: [{type:String}],
    currentStepIndex: {type: Number}
}) 

stepsSchema.plugin(uniqueValidator); 

stepsSchema.index({tid: 1})

module.exports = mongoose.model("Steps", stepsSchema);

需求与待完善代码

需要在findOneAndUpdate操作中,通过$switch分支实现以下逻辑:

  • 当actionFlow[currentStepIndex]对应的子数组内所有isPass字段均为true时,递增currentStepIndex
  • 当所有isPass均为false时,递减该值
  • 其余情况保持原值

当前待完善的查询代码如下:

steps = await Steps.findOneAndUpdate(
        { tid: tid },
        [{
         $set: {
         currentStepIndex:
          {  
            $switch: {
              branches: [
                {
                  case: { arrayElemAt: [`actionFlow`, `$currentStepIndex`] /* 需要补充判断所有isPass为true的逻辑 */},
                  then: 10,
                },
                {
                  case: { arrayElemAt: [`actionFlow`, `$currentStepIndex`] /* 需要补充判断所有isPass为false的逻辑 */},
                  then: -10,
                },
              ],
              default: '$currentStepElement', // 这里应为$currentStepIndex,属于笔误
            },
          },
        }
  }],

完善后的代码

结合MongoDB的$allElementsTrue、$map等操作符,可实现所需判断逻辑,最终代码如下:

steps = await Steps.findOneAndUpdate(
  { tid: tid },
  [
    {
      $set: {
        currentStepIndex: {
          $switch: {
            branches: [
              // 情况1:当前子数组所有isPass均为true,递增索引
              {
                case: {
                  $allElementsTrue: {
                    $map: {
                      input: { $arrayElemAt: ["$actionFlow", "$currentStepIndex"] },
                      as: "item",
                      in: "$$item.isPass"
                    }
                  }
                },
                then: { $add: ["$currentStepIndex", 1] }
              },
              // 情况2:当前子数组所有isPass均为false,递减索引
              {
                case: {
                  $allElementsTrue: {
                    $map: {
                      input: { $arrayElemAt: ["$actionFlow", "$currentStepIndex"] },
                      as: "item",
                      in: { $not: "$$item.isPass" }
                    }
                  }
                },
                then: { $add: ["$currentStepIndex", -1] }
              }
            ],
            // 其余情况保持原索引值
            default: "$currentStepIndex"
          }
        }
      }
    }
  ],
  // 如需返回更新后的文档,需添加该选项
  { new: true }
);

逻辑说明

  1. 判断所有isPass为true:

    • 用$arrayElemAt取出actionFlow中对应currentStepIndex的子数组
    • 通过$map将子数组每个元素映射为isPass字段的值
    • 最后用$allElementsTrue验证映射后的数组是否全为true
  2. 判断所有isPass为false:

    • 取出目标子数组后,用$map将每个元素的isPass取反($not)
    • 再用$allElementsTrue验证取反后的数组是否全为true,等价于原数组所有isPass均为false
  3. 默认情况:直接保留原currentStepIndex的值,同时修正了原代码中的笔误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 12:40:23