javascriptmongodbmongodb-stitch

How to increment existing value in MongoDB


I am using Stitch platform by MongoDB. I want to store a value and a count associated with that value in the database. Now the value may not be present for the first time, so I would like to insert the value with count = 1. I can use update() to update the existing value of count using $inc or I can use upsert() to add the value in the database. Now, the thing is, I have a map of my values and the count, and I want to insert(update/upsert) all at once. I don't want to put a load on the network. I was using insertMany() to insert the map at once but it clearly doesn't updates the value.

So is it possible to do so?

P.S. I am using javascript for the same.


Solution

  • According to MongoDb 3.6:

    db.collection.update(query, update, options)

    Modifies an existing document or documents in a collection. The method can modify specific fields of an existing document or documents or replace an existing document entirely, depending on the update parameter.

    The meaning is that you can upsert multiple documents using update.

    First you should create array from your map that contains only the value.

    const arrayOfValues = ['value_01', 'values_02'];
    

    Then you should use the upsert + multi options on the update method:

    db.foo.update({value: { $in: arrayOfValues}}, {$inc: {count:1}}, { upsert: true, multi: true });
    

    Test output:

    > db.createCollection("test");
    { "ok" : 1 }
    
    > db.test.insertMany([{value: "a"}, {value: "b"}, {value: "c"}]);
    {
        "acknowledged" : true,
        "insertedIds" : [
            ObjectId("5a48b8061b98cc5ac252e435"),
            ObjectId("5a48b8061b98cc5ac252e436"),
            ObjectId("5a48b8061b98cc5ac252e437")
        ]
    }
    
    > db.test.find();
    { "_id" : ObjectId("5a48b8061b98cc5ac252e435"), "value" : "a" }
    { "_id" : ObjectId("5a48b8061b98cc5ac252e436"), "value" : "b" }
    { "_id" : ObjectId("5a48b8061b98cc5ac252e437"), "value" : "c" }
    
    > db.test.update({value: { $in: ["a", "b", "c"]}}, {$inc: {count:1}}, { upsert: true, multi: true });
    WriteResult({ "nMatched" : 3, "nUpserted" : 0, "nModified" : 3 })
    
    > db.test.find();
    { "_id" : ObjectId("5a48b8061b98cc5ac252e435"), "value" : "a", "count" : 1 }
    { "_id" : ObjectId("5a48b8061b98cc5ac252e436"), "value" : "b", "count" : 1 }
    { "_id" : ObjectId("5a48b8061b98cc5ac252e437"), "value" : "c", "count" : 1 }
    
    > db.test.update({value: { $in: ["a", "b", "c"]}}, {$inc: {count:1}}, { upsert: true, multi: true });
    WriteResult({ "nMatched" : 3, "nUpserted" : 0, "nModified" : 3 })
    
    > db.test.find();
    { "_id" : ObjectId("5a48b8061b98cc5ac252e435"), "value" : "a", "count" : 2 }
    { "_id" : ObjectId("5a48b8061b98cc5ac252e436"), "value" : "b", "count" : 2 }
    { "_id" : ObjectId("5a48b8061b98cc5ac252e437"), "value" : "c", "count" : 2 }
    
    > db.test.update({value: { $in: ["a", "b", "c"]}}, {$inc: {count:1}}, { upsert: true, multi: true });
    WriteResult({ "nMatched" : 3, "nUpserted" : 0, "nModified" : 3 })
    

    Hope it was helpful :)