5

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.

Nikhil Wagh
  • 1,376
  • 1
  • 24
  • 44

1 Answers1

4

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"}];
... );
2017-12-31T12:12:18.040+0200 E QUERY    [thread1] SyntaxError: missing ) after argument list @(shell):1:61
> 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 :)

Ponpon32
  • 2,150
  • 2
  • 15
  • 26
  • Actually, I was working with javascript, so it would have been great if I could know how to do that in javascript. But it's okay, at least now I know where to begin with. – Nikhil Wagh Dec 28 '17 at 18:06
  • can you please provide the source of your answer.. it would be really helpful. – Nikhil Wagh Dec 29 '17 at 04:20
  • @Yochai_Akoka I tried to run this command `db.test.update({value: {$in: ["b","a"]}}, {$inc: {count:1}}, {upsert: true, multi: true})` but it doesn't upsert any thing in the database. My db already had `value: "a"` with `count:1` and I wanted to upsert `value:"b"` with `count:1` and increase the count for `value:"a"`. It only increases the count of values already present in the db. – Nikhil Wagh Dec 29 '17 at 07:35
  • i added to my answer also a test output from my console. – Ponpon32 Dec 31 '17 at 10:14