简体   繁体   中英

Conditionally remove or add element in document array using mongoose

I have the following incoming object from front end:

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

Mongo Schema: Sets

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

Let's assume that the document has the following items:

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

Then using this snippet I try to update the documents but it always removes the last item from the request.

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'));
    }
 });
});

How i can update the documents regarding the sets array in the req.body ?

Example:

User could select both tests, 1 & 2 , then all tests in the Sets model should have both.

Then, the user decides to select only 1 , then the test with id 2 should be removed from the array and so on.

Solved it by looping the cursor:

id is coming from the req.params , it's the test id

sets array is coming from 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()
      }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM