$addToSet and $arrayFilters combined

Hi, I would like to use both $addToSet and $arrayFilters functionalities. In particular, assuming I have the followign document design:

_id: ObjectID
folders: [
       id: string
       name: string

I would like to insert a new folder object (both name and id properties) if the id property does not exist yet, while I would like to update the existing folder object with the given id property if it already exists.
Is it possible with a single query operation?

Hi @Matteo_Tarantino
I don’t understand very well.

Is the uniqueness of the set is defined by the name, id, or both?

You may have [{name:'a'},{id:'1',name:'a'}] so {name:'a', id:'1'} would update 2 docs to the same value, or we may need to remove all docs with the same name first.

The uniqueness of the folder is its id property. I update only one doc at a time given its _id property.
Given a new folder (id and name), the main goal is:

  1. Append a new folder object if does not exists any object in the folders property with the given id
  2. Overwrite the existing folder object if already exists a folder with the given id

It would be easier to help you if you could provide sample starting documents, sample update operations with resulting documents for all the cases you want to support.

We could work out of your description but coming up with documents that matches your schema is tedious. Real documents is easier as we simply cut-n-paste them in our environment.

May be not a single query but a single server round trip with a bulkWrite with 2 queries and 2 different updates on the same documents. This is the idea but it is untested.

new_folder = { "id" : ... , "name" : ... }
// query_1 and update_1 is to replace existing folder
query_1 = { "filter" : { "_id" : id , "folders.id" : new_folder.id } }
update_1 = { "update" : { "$set" : { "folders.$" : new_folder } } }
// query_2 and update 2 is to add non existing folder
query_2 = { "filter" : { "_id" : id , "folders" : { "$not" : { "$elemMatch" : { "id" : new_folder.id } } } } }
update_2 = { "update" : { "$push" : { "folders" : new_folder } } }
c.bulkWrite( [ { "updateOne" : { ...query_1 , ...update_1 } } , { "updateOne" : { ...query_2 , ...update_2 } } ] )

As you already say it is not a single query but it should work!
Thank you!

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.