arraysmongodbincrementembedded-databasedocuments

MongoDB - Increment Nested Array of Documents Where Not Null


I have the following example document structure:

{
    "_id" : 1,
    "distributor" : "Jackson",
    "systems" : [
        {
            "name" : "XBOX",
            "quantity" : null,
        },
        {
            "name" : "PlayStation",
            "quantity" : 10,
        },
        {
            "name" : "Nintendo",
            "quantity" : 20,
        },
        {
            "name" : "Atari",
            "quantity" : null,
        },
    ],
    "games" : [
        {
            "name" : "Call of Duty",
            "quantity" : 5
        },
        {
            "name" : "Super Mario Bros",
            "quantity" : null,
        },
        {
            "name" : "Madden",
            "quantity" : 4,
    ],
    "comments" : null,
    "contact" : "Bill"
}

I want to increment the quantity of each NOT NULL embedded document by 1. So far, I am able to get it to update the 1st found not null entry (in this case, Playstation) but nothing else.

My desired outcome would look like this:

{
    "_id" : 1,
    "distributor" : "Jackson",
    "systems" : [
        {
            "name" : "XBOX",
            "quantity" : null,
        },
        {
            "name" : "{PlayStation}",
            "quantity" : 11,
        },
        {
            "name" : "Nintendo",
            "quantity" : 21,
        },
        {
            "name" : "Atari",
            "quantity" : null,
        },
    ],
    "games" : [
        {
            "name" : "Call of Duty",
            "quantity" : 6
        },
        {
            "name" : "Super Mario Bros",
            "quantity" : null,
        },
        {
            "name" : "Madden",
            "quantity" : 5,
    ],
    "comments" : null,
    "contact" : "Bill"
}

Thanks for any guidance!


Solution

  • If you're using MongoDB 3.6 or higher you can use arrayFilters.

    db.col.update(
       {_id: 1},
       { $inc: { "systems.$[elem].quantity": 1, "games.$[elem].quantity": 1 } },
       { arrayFilters: [ { "elem.quantity": { $ne: null } }  ] });
    

    Array filter simply applies your condition to each element of an array and executes your update if that particular element matches.