[SERVER-12754] $type not applied to nested elements of specific (dot notation) first-level array element Created: 17/Feb/14 Updated: 06/Dec/22 Resolved: 02/Aug/19 |
|
| Status: | Closed |
| Project: | Core Server |
| Component/s: | Querying |
| Affects Version/s: | 2.5.5 |
| Fix Version/s: | None |
| Type: | Bug | Priority: | Major - P3 |
| Reporter: | Thomas Zahn | Assignee: | Backlog - Query Team (Inactive) |
| Resolution: | Done | Votes: | 2 |
| Labels: | query-44-grooming | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Environment: |
> db.serverBuildInfo() |
||
| Attachments: |
|
||||||||||||||||||||
| Assigned Teams: |
Query
|
||||||||||||||||||||
| Operating System: | ALL | ||||||||||||||||||||
| Steps To Reproduce: |
The query:
|
||||||||||||||||||||
| Participants: |
| Description |
|
From the documentation of $type:
Unfortunately, the $type operator does not seem to get properly applied if the field is itself a concretely named (dot notation) (first-level) array element.
Suppose one now wanted to find those documents where the specific first-level element a.0 is itself an array and contains String elements:
Nothing comes up even though a.0 contains String elements in all documents. Note that trying to achieve this via the $elemMatch route does work:
However, it seems rather inefficient to first apply a check for a "field" 0 on potentially all array elements of a when one already knows the concrete element to investigate. (On a side note, I have always found it rather peculiar that $type is applied to the elements of an array field rather than to the field itself when {"$elemMatch" : {"$type" : <id>}} already captures these desired semantics) This seems somewhat related to |
| Comments |
| Comment by David Storch [ 02/Aug/19 ] |
|
This behavior appears to be working as designed. When a positional path component – like the "0" or "1" in this issue report – resolves to an array index, nested arrays are not implicitly traversed. Consider the simpler example of the document {a: [["foo", "bar"]]}. The path "a.0", when resolved against this document, will treat "0" as an array index. It will cause the match expression evaluation code to extract the zeroth element of the outer array, which in this case is the inner array ["foo", "bar"]. However, the matcher semantics are to not implicitly traverse an inner array after extracting an array element my index. Therefore, neither the query {"a.0": {$eq: "foo"}} nor {"a.0": {$eq: "bar"}} matches this document. (In contrast, {"a.0.0": {$eq: "foo"}} and {"a.0.1": {$eq: "bar"}} both match the document.) This slightly simpler query is exactly analogous to the one with $type in the description of this ticket. |
| Comment by Benety Goh [ 06/Mar/14 ] |
|
FYI, test script gives the same results in 2.4 |