Robert Weindl
Robert Weindl

Reputation: 1092

mongoose - Add if not in array, remove if already in array

What is the fastest way in mongoose to determine if an element is already in an array. In that case I want to delete the element from that array. In the case the array doesn't contain the specific element I want to add it.

Of course adding and removing can be done with addToSet and remove(_id). Querying is also no problem. I really care more about the shortest way to do this, with less effort.

For example I suggest to take the Schema:

var StackSchema = new Schema({
    references: [{ type: Schema.Types.ObjectId, ref: 'Person' }]
});

Let's say the the references array contains the elements:

['5146014632B69A212E000001',
 '5146014632B69A212E000002',
 '5146014632B69A212E000003']

Case 1: My method receives 5146014632B69A212E000002 (So this entry should be removed.)

Case 2: My method receives 5146014632B69A212E000004 (So this entry should be added.)

Upvotes: 1

Views: 2122

Answers (3)

user7075574
user7075574

Reputation:

@Hussein answer, but using Lodash:

const _ = require("lodash")

const User = require("./model")

const movies = ["Inception", "Matrix"]

(async () => {
    // Catch errors here
    const user = User.findById("")

    const userMoviesToggle = _.xor(
        user.movies, // ["Inception"]
        movies
    ); // ["Matrix"]

    user.movies = userMoviesToggle

    // Catch errors here
    user.save()
})()

Upvotes: 0

Hussein Nazzal
Hussein Nazzal

Reputation: 2557

the solution for anyone passing by . :)

if(doc.references.indexOf(SOMESTRING) !== -1) {
    console.log('it\'s there') ; doc.likes.pull(SOMESTRING);
}else{
    doc.references.push(SOMESTRING);
}

Upvotes: 2

nevi_me
nevi_me

Reputation: 2730

Here's the logic, with code below.

I normally use underscore.js for such tasks, but you could do it in just JavaScript.

  1. fetch the document.
  2. iterate through the _ids in the document, performing a truth test.
  3. If the document has the _id that you're testing, delete the current index from the array.
  4. If you've gone through the whole array and there's nothing in there, array.push() the _id. Then document.save()

That's the approach that I normally follow.

In underscore, it'd go something like this:

function matching(a,b) { // a should be your _id, and b the array/document
  var i;
  for ( i = 0, i < b.length , i++) {
    if ( a.toString() === b[i].toString() )
      return i;
    else return -1;
  }
};

Then you'd use the function thus:

var index = matching( '5146014632B69A212E000002', doc );
if ( index > -1 )
  doc.splice( index , 1);
else 
  doc.push( '5146014632B69A212E000002' );

Upvotes: 0

Related Questions