首页 > 解决方案 > 使用猫鼬有条件地删除或添加文档数组中的元素

问题描述

我有以下来自前端的传入对象:

{
 name: "Test 1",
 sets: [1,2]
}

蒙戈模式: Sets

name: {
        type: String
      },
tests   : [{
        type: Schema.Types.ObjectId,
        ref : 'Test'
    }]

假设文档有以下项目:

[
 {
  name: "Test Set 1",
  tests: [],
  id: 1
 },
 {
  name: "Test Set 2",
  tests: []
  id: 2
 }
]

然后使用这个片段我尝试更新文档,但它总是从请求中删除最后一项。

const {sets} = req.body;
const {id} = req.params;

const tests = await Set.find({_id: {$in: sets}}).exec();

sets.forEach(async set => {
      tests.forEach(async test => {
        if (set !== test._id) {
         await Set.update({_id: test._id},
           {$addToSet: {tests: id}},
           {upsert: true})
       .exec((err, res) => console.log(err, res, 'ADDTOSET'));
     } 
else {
       await Set.updateMany({tests: {$elemMatch: {$eq: id}}},
          {$pull: {tests: id}}, {multi: true})
       .exec((err, res) => console.log(err, res, 'PULL'));
    }
 });
});

我如何更新有关sets数组中的文档req.body

例子:

用户可以选择两个测试1& 2,然后模型tests中的所有测试都Sets应该同时具有。

然后,用户决定只选择1,然后应该从数组中删除testwithid 2等等。

标签: javascriptnode.jsmongodbmongoose

解决方案


通过循环游标解决它:

id来自req.params,它是test id

sets数组来自req.body.

import mongoose from 'mongoose';

const cursor = Set.find({}).cursor();

for (let set = await cursor.next();
     set != null;
     set = await cursor.next()) 
      {
      if (!set.tests.includes(mongoose.Types.ObjectId(id)) && !sets.includes(set._id.toString())) {
         await Set.update({_id: set._id}, {$pull: {tests: id}}, {new: true, upsert: true}).exec();
      } else {
         await Set.updateMany({_id:  {$in: sets}}, {$addToSet: {tests: id}}, {new: true}).exec()
      }
}


推荐阅读