Update multiple documents without for loop MongoDB

Viewed 54

I want to increment by 1 the tag number of each Tag in a given array of many Tags.

I specify that the Tag may not exist so i need to create the "tag" field when it doesn't exist with the correct value for each individual tag in the array (json["tags"] here).

I would like to perform this in one query with MongoDB, something that would look like this :

tags_collection.update_many(
            {
                "tag": {"$in": json["tags"]},
            },
            {
                "$set": {"tag": "<value of the tag found>"},
                "$inc": {"num": 1}
            },
            upsert=True
        )

I simply want to avoid the for loop with many update_one that of course would work but would make until 50 queries in my case...

EDIT :

Let's say I split the above query as suggested in the comment in 2 queries :

tags_collection.update_many({"tag": {"$in": json["tags"]}}, {"$inc": {"num": 1}})

and :

tags_collection.update_many({"tag": {"$exists": False}}, {"$set": {"tag": "<value of the tag found>"}}, upsert=True)

The question is then :

  • How can i know the <value of the tag found> ? In other words, how i can create new documents with all the tags that were not updated by the first query, in a single request ?

I would like to avoid reading the database first if possible, but if i have no choice will do.

1 Answers

If tag does not exists in the document you can't filter on its value.
You can split your query to:

tags_collection.update_many({"tag": {"$in": json["tags"]}}, {"$inc": {"num": 1}})
tags_collection.update_many({"tag": {"$exists": False}}, {"$set": {"tag": "<value of the tag found>"}}, upsert=True)

Watch the documentation on mongodb here

Related