1

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 Answer 1

1

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

Sign up to request clarification or add additional context in comments.

7 Comments

Thanks for the answer ! However, how can i know the tags that were not updated from the first query to set the correct "<value of the tag found>" please ? Besides in your second query, the update_many doesn't seem needed as i can do only one by one right ? I need to write 1 document per Tag
I don't understand your first question, can you please elaborate what is the first query and the second one? And yes, you can do it one by one but its preferred to preform one operation - so organize the array you want to insert and use insert_many
I have edited the question, please let me know if this is clear enough. The first and second queries were yours actually based on your answer. Indeed i am thinking of insert_many but this would require reading the database first to get existing tags right ? in order to organize the array , but I would prefer avoid doing that, unless i have no choice
I don't think you can do it at once. Yes you will have to read what tags do you have, but you can wrap it all with a transaction so you'll be sure everything is done or not.
Note you always have only three queries - one for reading (find), one for updating existing tags (update_many) and one for insert new ones (insert_many). If you really insist, maybe you could find something with aggreagte and $unwind to json["tags"]
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.