[SERVER-67539] Discrepancy in `showRecordId()` behavior Created: 27/Jun/22 Updated: 27/Oct/23 Resolved: 18/Aug/22 |
|
| Status: | Closed |
| Project: | Core Server |
| Component/s: | None |
| Affects Version/s: | None |
| Fix Version/s: | None |
| Type: | Bug | Priority: | Major - P3 |
| Reporter: | Denis Grebennicov | Assignee: | David Storch |
| Resolution: | Works as Designed | Votes: | 0 |
| Labels: | None | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Issue Links: |
|
||||||||
| Operating System: | ALL | ||||||||
| Sprint: | QE 2022-07-25, QE 2022-08-08, QE 2022-08-22 | ||||||||
| Participants: | |||||||||
| Description |
|
While working on `showRecordId()` is a shell method which "modifies the output of a query by adding a field $recordId to matching documents". While running the following queries, I assumed that all of them should have `$recordId` in their output. However, this is only the case for the first one.
Here is the output:
showRecordId() documentation → https://www.mongodb.com/docs/v6.0/reference/method/cursor.showRecordId/
PS: the issue also doesn’t seem to be SBE or classic engine specific. |
| Comments |
| Comment by David Storch [ 18/Aug/22 ] | ||||||||||
|
Following up on the behavior of this query:
It looks like the behavior changed in 4.4 as part of the project to rewrite the projection implementation (PM-684). In 4.2, the result set includes a "$recordId" field and in 4.4+ it does not. The reason is as I described above: if the projection already refers to the "$recordId" field, the implementation avoids overwriting it with a "recordId" $meta projection. I think we should close this as "Works as Designed" for a few reasons. Looking at the design document for PM-684, I'm guessing that we made this change purposefully. The behavior change was made awhile ago and has been around for several major releases without causing any practical problems. Also, the showRecordId() feature is not intended for use in application queries, but presumably is used only in limited debugging scenarios. Finally, there remains a way to write a query which includes _id and "$recordId" but excludes other fields. This query does the trick:
Although I'm closing this as "Works as Designed", I also filed | ||||||||||
| Comment by David Storch [ 27/Jun/22 ] | ||||||||||
|
denis.grebennicov@mongodb.com anton.korshunov@mongodb.com it looks like the showRecordId find command option is internally translated to the projection {$recordId: {$meta: "recordId"}}. This is because the behavior of showRecordId is to add a field to each document with the field name "$recordId". It looks like the behavior observed in this ticket is because of this code: If there's already a user projection on "$recordId", then we are careful not to overwrite it with an internally generated $meta projection. The other interesting wrinkle, however, is that it looks like in general we do not permit $-prefixed field names in projection specifications:
I guess because we use the name "$recordId" internally, we have some special-casing to permit this case. You could argue that this is itself a bug and the user should not be permitted to use the name "$recordId", but it might be awkward for the implementation to distinguish between user projections and internally generated ones. Last, I notice that the documentation includes this example:
The docs suggest that this query used to mean "show the record ids and project out everything but _id and $recordId". If so, then we might have made a breaking change at some point. I suggest that as a first step we check how this query behaves against all supported major versions of the server. |