Click an element into an array if it is absent (no duplicates)

I have an event collection that I look through to find a category for a specific event, and then I update my other collection with the $ push operator. The problem is that when two events have the same category, it will create a duplicate that I don't need.

I know about upserts, but I'm not sure if this is the best way to go about this? And I'm a little confused when it comes to how to write a message that works with the "$ push" -statement.

Here's what my update looks like right now:

self.users.update({"user_id": event['userid']}, {'$push': {'campaigns': UserCampaign}}) 

.. where:

 UserCampaign = { "id": campaign['id'], "name": campaign['name'] } 

The "UserCampaign" is filled with the same information from time to time, and since my collection is likely to be very huge, I want to make it as efficient as possible.

TL; DR; I want to update the array in the found document using "push", without risking getting duplicates.

+6
source share
3 answers

Found the best answer to my problem:

Using $ addToSet, he did not create duplicates (I also did not duplicate what was done before, adding all the dictionaries to the list):

 self.users.update({"user_id": event['userid']}, {'$addToSet': {'campaigns': UserCampaigns[i]}}) 

If I just used $ push, it always created duplicate items in campaigns in the user collection. This happened with and without upsert.

For some reason, $ each did not work, but was not required, I think PyMongo will take care of this for me.

+11
source

Send the third argument of your update as true, as in MongoDB and PyMongo Docs Docs .

 self.users.update({"user_id": event['userid']}, {'$push': {'campaigns': UserCampaign}}, True) 
+9
source

Christian has the right arguments in his answer, so I will leave this part alone (supported his answer).

However, you are also asking for avoidance of duplicates, etc.

The key point here is to verify that part of the criteria for your update request depends on the level you want. An update (or update) is no worse than the criteria you pass into it. Upsert will add a new document if it does not find one that matches the criteria, and the update will only perform $ push (or any other update) if the criteria are met (you can update many times if more than one doc is also found).

In your case, part of the criteria:

 UserCampaign = { "id": campaign['id'], "name": campaign['name'] } 

Make sure that this part is unique and everything will be in order - if it can correspond to more than one document, then you will have duplicates.

+1
source

Source: https://habr.com/ru/post/917980/


All Articles