[SERVER-10907] aggregation usage for $allElementsTrue and $anyElementTrue operators with $project Created: 25/Sep/13 Updated: 10/Dec/14 Resolved: 27/Sep/13 |
|
| Status: | Closed |
| Project: | Core Server |
| Component/s: | Aggregation Framework |
| Affects Version/s: | None |
| Fix Version/s: | None |
| Type: | Bug | Priority: | Major - P3 |
| Reporter: | Gary Murakami | Assignee: | Unassigned |
| Resolution: | Done | Votes: | 0 |
| Labels: | 26qa | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Issue Links: |
|
||||
| Operating System: | ALL | ||||
| Steps To Reproduce: | > db.people.save( {name: 'Gary'}) } } ) > db.people.aggregate({ $match: { } }, { $project: { new: { $allElementsTrue: [[true]] } } } ) ], |
||||
| Participants: | |||||
| Description |
|
$anyElementsTrue should take a "simple" array as an argument, but gives a usage error. If the argument is an array with a single element of an array, then it functions but not as expected or desired. The arg should be just the "simple" array - discussed with Matt. |
| Comments |
| Comment by Gary Murakami [ 30/Sep/13 ] | |||
|
Mathias, thanks for the explanation. | |||
| Comment by Mathias Stearn [ 30/Sep/13 ] | |||
|
That passes two arguments to the allElementsTrue function.
Doesn't do what you want either. It passing a single array, however it is a constant array containing the two strings "$$var1" and "$$var2", which mean would always return true since strings are always true. Unfortunately there is no good way to create an array like that currently. The solution proposed in
BTW, the best way to express this expression is also the simplest and works just fine currently:
| |||
| Comment by Gary Murakami [ 30/Sep/13 ] | |||
|
The following seems like a reasonable use case.
| |||
| Comment by Mathias Stearn [ 30/Sep/13 ] | |||
|
The thing is that users would never pass in an array to these expressions. That only comes up in the case when passing a constant array in which case you could just pass a constant true or false value. The realistic use case is passing another expression as the argument which works well
In these cases, the argument is allowed, but not required to be wrapped in an array. Admittedly, aggregation does need better tools to work with arrays. I think something like | |||
| Comment by Gary Murakami [ 30/Sep/13 ] | |||
|
To clarify, as a user, I expect to be able to express $allElementsTrue or $anyElementTrue with a value that is a simple array as follows.
As a user, I do not expect to be forced to use a nested array as follows.
The latter is bound to generate a lot of user confusion and complaint, and I do not think that it was our original intent, but just the result of ease of internal implementation. | |||
| Comment by Mathias Stearn [ 25/Sep/13 ] | |||
|
You will have to do this to make it work:
The issue is that the general syntax for "regular" agg expressions is {$opName: [arg1, arg2,...]}. As a convenience, if you are only passing a single argument you are allowed to omit the wrapping array and just do {$opName: arg1}. This creates an ambiguity when it looks like you are passing a single array when really you are passing it's contents as arguments. In this specific case, note that Arrays are considered "truthy" so {$anyElements: [[[1,2,3]]]} would be valid and always return true since the only argument is an array with a single "true" value. |