Has $addToSet improvement for specifying key already been discussed?

My question is based on this StackOverflow question

Currently, having a document with embedded array of documents, the $addToSet operation compare each of the fields of the nested document (or the hash of the nested document. I am not aware how was implemented).

It will be great if we have the possibility to specify key / field that will be used in making the decision whether the document we try to add already exists

The proposed answer in the SO question is fine for adding only one element. Adding more elements the same way (with query for existence of the nested document) may lead to loosing the benefits оф ACID features for working with single document because of the multiple separate update statements that should be executed. Even bulk updates don’t fix the problem.

Looking at the question, It seems to me that It is a popular one. I am wandering whether adding such feature for $addToSet operation have been ever discussed. It will be nice if it is available in the future and fix the problems described above.

P.S. I know that I can use multi-document transactions but I don’t think using them for such case is appropriate.

As of 4.2 there is a way to do this using aggregation expressions in update. There are some examples too.

For your case, you would have to do something like this:

Starting document:

{ _id: 1, 
  array: [
     { a: "Foo", other: 26 },
     { a: "Bar", other: 99 }
]}

You want to add two subdocuments, one with a:"Bar" which already exists and should be ignored, and a:"Baz" which doesn’t exist and should be added… I guess specifics would depend on whether other fields exist and whether they should be ignored or “merged” in, but let’s say they should be ignored entirely, update would be something like:

newSubDocs = [ { a: "Bar" }, { a:"Baz" } ];
db.coll.update( { _id:1 },
  [ 
     {$set:  { array:  {$concatArrays: [ 
          "$array",  
          {$filter: {
                 input:newSubDocs, 
                 cond: {$not: {$in: [ "$$this.a", "$array.a" ]}} 
          }}
     ]}}}
  ]
)

Result:

{ "_id" : 1, 
  "array" : [ 
      { "a" : "Foo", "other" : 26 }, 
      { "a" : "Bar", "other" : 99 }, 
      { "a" : "Baz" } 
] }

If you want to do some sort of merge if the key field already exists, then the example is a bit more complex but I have something analogous to it in my MongoDB World 2019 talk starting around minute 21.