[SERVER-19172] Allow logical operators on non-top-level expressions in $pull operations Created: 27/Jun/15 Updated: 06/Dec/22 Resolved: 29/Jun/19 |
|
| Status: | Closed |
| Project: | Core Server |
| Component/s: | Write Ops |
| Affects Version/s: | None |
| Fix Version/s: | None |
| Type: | Improvement | Priority: | Minor - P4 |
| Reporter: | Blakes Seven | Assignee: | Backlog - Query Team (Inactive) |
| Resolution: | Won't Do | Votes: | 1 |
| Labels: | None | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Assigned Teams: |
Query
|
| Participants: |
| Description |
|
It would be desirable to allow logical operators over non-top-level expressions in $pull operations. Currently, the following is an error, and there is no equivalent way to express it in one update:
Original description:
Now let's say I want to $unset the first occurence of 5 in the array, so the you could do:
Which is all fine as now the first of the values for 5 is null:
But now if you want to remove both "null" and values "less than" 4 you need to perform several updates:
So the current syntax to $pull seems to consider that the immediate "key" identifier inside the $pull operation needs to be the identifier for the array from which the items would be pulled from. It would be nicer if full query conditions could be set such as:
But there is of course an ambiguity on "which field" is set for the array within an $or condition. That does not error presently, but of course does not work either. A possible alternate syntax could be:
Being a shorter version of $or via $in, but of course that does error due to $in not allowing such a contruct for evaluation. On the other hand using $pullAll does not error here:
But of course only removes "null" values and ignores the conditional statement as a literal. There must be some way to work the syntax in for multiple conditions without performing multiple update operations. Even the first $or example would be fine if there were some check to make sure you were not operating a condition on a different document element within the $pull operation, so that both elements had to be "foo.bar" in this case. Allowing this but producing an error where the field conditions did not match would seem a valid approach. |
| Comments |
| Comment by Asya Kamsky [ 29/Jun/19 ] | ||||||||||
|
You can see some examples here. This can be done by setting the array to its new value using aggregation array expression $filter which takes arbitrarily complex conditional. | ||||||||||
| Comment by Asya Kamsky [ 29/Dec/17 ] | ||||||||||
|
On the other hand, this syntax:
does not work. | ||||||||||
| Comment by Asya Kamsky [ 29/Dec/17 ] | ||||||||||
|
Of the original examples:
| ||||||||||
| Comment by Benjamin M [ 28/Jun/15 ] | ||||||||||
|
With an array of documents this works pretty well:
Here you can also use $or and everything else. Though I'd suggest that this should be the right syntax for a simple array of values:
Because this already works:
(see here: http://docs.mongodb.org/manual/reference/operator/update/pull/#remove-all-items-that-match-a-specified-pull-condition ) |