Search code examples
node.jsmongodbsails.jswaterline

Unable to push an item into a MongoDB array within the document while using Waterline


I'm struggling with an update call that just doesn't seem to work for some reason. For some quick context, we have a Node.js application running on Sails.js with Waterline ORM.

As per my package.json file, here are the versions I am using:

  • connect-mongo: ^1.3.2
  • mongodb: ^2.2.29
  • sails: ~0.12.4
  • sails-mongo: ^0.12.3

I have a collection called "products" and each product looks like this in the database:

{
    "_id" : ObjectId("59d5f12025423dc0261c911d"),
    "category" : ObjectId("59a9bcf984d756998eaa22e5"),
    "status" : "pendingReview",
    "isDeleted" : false,
    "events" : [
        {
            "when" : 1507193120,
            "actor" : "56cc0f76e1a25cde0d2c15ab",
            "action" : "Submitted product",
            "note" : "Jeff added this product. It is awaiting review."
        }
    ],
    "productId" : "171005-00000",
    "createdAt" : ISODate("2017-10-05T08:45:20.538Z"),
    "updatedAt" : ISODate("2017-10-05T08:45:20.538Z")
}

I have a UI where a user can "approve" multiple products before they are displayed to website visitors. To do this, I want to just update multiple records by changing the status key to "approved" and adding an event in the events array of each document. The event must be in position 0 of the array. I am trying to update these records with the following code but it doesn't seem to work:

var moment = require('moment');
Products.native(function(error, collection) {

    if (error) {
        throw error;
    }

    collection.update(
        { _id: ['59d5f12025423dc0261c911d'] },
        { 
            $set: {
                status: 'approved',
                $push: {
                    events: {
                        when: moment().unix(),
                        actor: req.body.userId,
                        action: 'Approved product',
                        note: req.body.userName + ' approved this product.'
                    }
                }
            }
        },
        { multi: true },
        function(error, count, status) {

        if (error) {
            sails.log.error(error);
            return res.serverError('Database error. Reference ID: ' + req.referenceId);
        }

        return res.ok(count);
    });
});

When I run this query, I don't get any error and when I check my database, the record has not been updated. I get the following data when I run the query:

{
    "ok": 1,
    "nModified": 0,
    "n": 0
}

What's going on here? Why isn't getting updated? If I understand correctly, the query is able to find the document but it isn't getting updated. Is that correct? If yes, how do I resolve this? Thanks.


Solution

  • $push should be at the same level as $set. They are both operators...

    This means you should change like this:

    { 
        $set: {
            status: 'approved'
        },
        $push: {
            events: {
                when: moment().unix(),
                actor: req.body.userId,
                action: 'Approved product',
                note: req.body.userName + ' approved this product.'
            }
        }
    }