Bob Singor
Bob Singor

Reputation: 578

Push object to a mongoose array and check for duplicate fields inside the array objects

I am trying to push a notification object to a mongoDB array with the follow condition:

Check if there is a notification inside the array with the same postId If yes: return that object If no: create a new notification object

I'm using node with Mongoose ODM. In some other questions online they give this as an answer:

user.update({'notifications.postId': {$ne: post._id}}, {$push: { 'notifications': {type: 'POST', postId: post._id}}}, function(err, doc) {
  .....
});

But this didn't work for me.

Below you find the structure of the mongodb document.

{
    "_id": {
        "$oid": "56631b22067ee41847dab6bb"
    },
    "unreadNotifications": 0,
    "notifications": [
      {
        "type": "POST",
        "postId": {
          "$oid": "5666b78b61eb95bc03d47a71"
        },
        "_id": {
          "$oid": "56782daa395840efd4ed3f7a"
        },
        "createdAt": {
          "$date": "2015-12-21T16:49:46.903Z"
        },
        "events": []
      }    
    ]
    "created": {
        "$date": "2015-12-05T17:13:06.782Z"
    },
    "lastName": "Power",
    "firstName": "John",
    "__v": 0
}

Upvotes: 2

Views: 1025

Answers (1)

MooYeol Prescott Lee
MooYeol Prescott Lee

Reputation: 56

Note that Schema#update method will not updating records because there are no matched records described by specified match condition.

Anyway, You can create your own method on your User Schema.

Example

UserSchema.method('sendNotification', function (post, done) {
    var notification = null;

    for (var i = 0, len = this.notifications.length ; i < len ; i++) {
        notification = this.notifications[i];
        if (notification.postId.equals(post._id)) {
            return done(null, notification);
        }
    }

    notification = {
        type: 'POST',
        postId: post._id
    };

    this.update({
        $push: {
            notifications: notification
        }
    }, function (e, doc) {
        if (e) { return done(e); }
        return done(null, notification);
    });
});

You can use this method after model was created.

User.findOne({
    email: '[email protected]'
}).exec(function (e, john) {
    john.sendNotification(post, function (e, notification) {
        if (e) { console.log('Ah snap! There are an error.'); }
        console.log('notification: ', notification);
    });
});

Upvotes: 1

Related Questions