1
votes

What I am trying to do I have a document with teamid as the unique identifier and name of the team. I have an array 'teamList' in my model which would hold the names of all the team members. When a new member is added, I only want names which are not existing to be added. So, if a name is already present it should not be added.

PROBLEM I would like to ensure that there are no repeats inside the teamList array. But right now, all objects in the names array are added to the teamList despite using $addToSet and turning off _id inside the array.

Here is my schema:

var teamSchema = new Schema({
  teamid: {
    type: String,
    required: true
  },
  created: {
    type: Date
  },
  lastUpdated: {
    type: Date,
    default: Date.now,
    required: true
  },
  teamList: [{
    name: {
      type: String,
      required: true,
      unique: true
    },
    dateAdded: {
      type: Date,
      default: Date.now
    },
    _id:false
  }]
});
module.exports = mongoose.model('teamModel', teamSchema);

This is my code:

var mongoose = require('mongoose');
teamModel = mongoose.model('teamModel');
var names = [{name:'Robert'},{name:'Alice'},{name:'Bob'}];
var teamName = 'ManU';
teamModel.update({
        teamid: teamName
      }, {
        $addToSet: {
          teamList: {
            $each: names
          }
        }
      }, {
        upsert: true
      },
      function (err, data) {
       console.log(data);
      });

My question is similar to - http://blog.open-tribute.org/2015/05/09/NodeJS-Mongoose-addToSet-duplicates-on-objects/ , Avoid duplicate entries on Mongoose array

But $addToSet does not work for me probably because I am passing in an array to be added to the teamList array and so I would have to use $each (which is not covered in the previous questions)

1

1 Answers

1
votes

Your problem is that in the schema the teamList receive a name and a dateAdded, you are generating a new dateAdded for each update execution default: Date.now.

The statement $addToSet will check if the whole array object is duplicated or not.

enter image description here

{name : "Robert" dateAdded : 2018-07-14 14:06:09.749}

is different than:

{name : "Robert" dateAdded : 2018-07-14 14:06:12.473}

If you need to store the date when the new member is added you need to check it before the update.

One possible solution:

var teamPeople = [{name:'Robert'},{name:'Alice'},{name:'Bob'},,{name:'Ane'}];
  var teamName = 'ManU';
  var currentTeam = await TeamModel.findOne({teamid: teamName},{"teamList":1});
  for(var i=0;i < teamPeople.length;i++) {
    for (var j = 0; j < currentTeam.teamList.length; j++) {
      if (currentTeam.teamList[j].name === teamPeople[i].name) {
        //remove duplicate team member
        teamPeople.splice(teamPeople[j], 1);
      }
    }
  }
  console.log('New names:'+teamPeople);

  TeamModel.update({
      teamid: teamName
    }, {
      $addToSet: {
        teamList: {
          $each: teamPeople
        }
      }
    }, {
      upsert: true
    },
    function (err, data) {
      console.log(data);
    });