[SERVER-10974] Provide a Symmetric Difference operator to new set operators in aggregation framework Created: 30/Sep/13  Updated: 06/Dec/22

Status: Backlog
Project: Core Server
Component/s: Aggregation Framework
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major - P3
Reporter: Jacob Ribnik Assignee: Backlog - Query Execution
Resolution: Unresolved Votes: 2
Labels: expression
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Attachments: PNG File screenshot-1.png    
Issue Links:
Depends
Assigned Teams:
Query Execution
Participants:
Case:

 Description   

In the new set operators, there is not a symmetric difference operator. This is one of the 4 main operators (in addition to intersection, union, and relative complement) on sets that it seems should be part of the new set operators.

It probably would make sense to call this operator $setSymmetricDifference in order to follow the C++ naming convention of these operators.

There is currently a work around, but it is much slower than implementing in code:

db.colors.aggregate([
{'$project': { 
diff:{$setUnion:[{$setDifference:["$left","$right"]}, {$setDifference:["$right","$left"]}]}
}
}
]);



 Comments   
Comment by Scott Roberts [ 27/Mar/18 ]

Sure, there are any number of ways to do a symmetric difference with existing operators, but they all are just as convoluted to read. They are not readily apparent to someone looking at the code that someone is just trying to do this:

The suggestion is to add the feature so that you get a performance benefit of not having to do a bunch of different set operations and so that the code someone writes makes the intent more apparent.

Comment by Asya Kamsky [ 23/Jan/18 ]

It could also be done via:

db.colors.aggregate([
 {'$project': { 
     diff:{$setDifference:[{$setUnion:["$left","$right"]}, {$setIntersection:["$right","$left"]}]}
 } }
]);

Comment by Scott Roberts [ 11/Oct/13 ]

@Matt Dannenberg:
You are correct. It is not the symmetric difference, but rather the relative complement. We chose this name because it was consistent with most programming languages ( http://en.wikipedia.org/wiki/Complement_(set_theory)#Complements_in_various_programming_languages ). It would be possible to create a $setSymmetricDifference. If nothing else, this follows the C++ standard of std::set_difference and std::set_symmetric_difference. Would you mind filing a JIRA ticket requesting it? Feel free to suggest another name, if there is one you think is better.

Comment by Scott Roberts [ 11/Oct/13 ]

When I was going through the docs I think I went over the set operations too fast. It seems that the $setDifference operator is actually the relative complement, which I did not expect. There actually does not seem to be a true symmetric difference operation. When you look at all the set operations, the ones that don’t include the complement of the two sets are:
Union ($setUnion)
Intersection ($setIntersection)
Relative complement ($setDifference)
Symmetric difference
You could just get to it the following way, which could be fine. It would be a slower operation than a pure symmetric difference implementation.

db.colors.aggregate([
 {'$project': { 
     diff:{$setUnion:[{$setDifference:["$left","$right"]}, {$setDifference:["$right","$left"]}]}
 } }
]);

Generated at Thu Feb 08 03:24:32 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.