-
Notifications
You must be signed in to change notification settings - Fork 235
feat(hadron-document)!: handle nested fields and dots & dollars well COMPASS-5805 #3239
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…OMPASS-5805 - Instead of fully replacing top-level properties only when editing documents, set only the individual nested values that have been edited. - This does not apply to array item removals, since there is no way to perform this (at least in MongoDB 4.0, but doing so on newer versions is also not straightforward). - Use `$getField` and `$setField` to modify fields whose names contain dots or start with a dollar sign. This is kind of a breaking change in that, previously, we would have queried for the field names containing dots, the server would have interpreted the field name as referring to nested documents, almost never found a document matching that (unless the doc happened to have a shape like `{ x: { y: 2 }, 'x.y': 2 }` with matching values), and we then prompted the user to force-update due to the assumption that no document having been found means that it has been updated in the background. After this change, we just inform users that doing this properly requires MongoDB 5.0 or above. Users can still perform edits through the JSON view, at least for now (potentially only until COMPASS-5753 is done). - Split the query/update document generation parts into two steps, and move these out of the `Document` class to `ObjectGenerator` (which is already a collection of static methods for recursively traversing a document/element tree). - In the first step, gather all the elements that were updated, their original paths and values and their new paths and values. - In the second step, build either a query out of those original paths and values, or build the update document out of the new paths and values. - Drive-by bugfixes: - When renaming elements, we previously did not check that the new name was not already added in the background. We check this as well now. - Handle the case in which elements are renamed circularly, e.g. key2 → key3, key1 → key2 (or similar add/remove situations). - Use string arrays instead of objects that are only being used to extract their keys in the hadron-document API for hopefully a bit more API clarity. - Clarify in the docs that dots inside field names refer to nested documents. This is the way that sharding behaves, which is why we use them in the first place, and is not a practical API to break. (And if it does, there is an upcoming server sharding project will hopefully already have made inclusion of the shard keys unnecessary.) This also addresses COMPASS-5528 (which is about adjusting the update document sent to the server, whereas COMPASS-5805 is about adjusting the query document).
error.codeName === 'InvalidPipelineOperator' && | ||
error.message.match(/\$[gs]etField/) | ||
) { | ||
const nbsp = '\u00a0'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❤️
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! Learned a ton about how v5 handles dots and dollars fields updates 😊
): { | ||
query: BSONObject; | ||
updateDoc: { $set?: BSONObject; $unset?: BSONObject }; | ||
updateDoc: { $set?: BSONObject; $unset?: BSONObject } | BSONArray; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Totally can see that this PR is marked as a breaking change with a !
, but still wanted to highlight that cloud seems to have very hard expectations for this to return set / unset object here. Just wondering if we checked with them whether they would be able to handle this new format with their backed at all, maybe we should create a downstream ticket for them to look into this 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oof, thanks for bringing this up! Pinged them on Slack (as you might have seen)
…6011 Follow-up to c865b66 (#3239), which introduced this bug: Handle updates to arrays in the case in which the updated array (or another updated path) contains dots or starts with a dollar sign, using alternatives to `$getField` and `$setField` which can work on arrays (`$arrayElemAt` for the former, `$concatArrays` + `$slice` for the latter).
…6011 Follow-up to c865b66 (#3239), which introduced this bug: Handle updates to arrays in the case in which the updated array (or another updated path) contains dots or starts with a dollar sign, using alternatives to `$getField` and `$setField` which can work on arrays (`$arrayElemAt` for the former, `$concatArrays` + `$slice` for the latter).
…6011 (#3388) Follow-up to c865b66 (#3239), which introduced this bug: Handle updates to arrays in the case in which the updated array (or another updated path) contains dots or starts with a dollar sign, using alternatives to `$getField` and `$setField` which can work on arrays (`$arrayElemAt` for the former, `$concatArrays` + `$slice` for the latter).
documents, set only the individual nested values that have been
edited.
way to perform this (at least in MongoDB 4.0, but doing so
on newer versions is also not straightforward).
$getField
and$setField
to modify fields whose namescontain dots or start with a dollar sign.
This is kind of a breaking change in that, previously, we
would have queried for the field names containing dots,
the server would have interpreted the field name as referring
to nested documents, almost never found a document matching that
(unless the doc happened to have a shape like
{ x: { y: 2 }, 'x.y': 2 }
with matching values), and we thenprompted the user to force-update due to the assumption that
no document having been found means that it has been updated
in the background.
After this change, we just inform users that doing this
properly requires MongoDB 5.0 or above. Users can still perform
edits through the JSON view, at least for now (potentially only
until COMPASS-5753 is done).
and move these out of the
Document
class toObjectGenerator
(which is already a collection of static methods for recursively
traversing a document/element tree).
their original paths and values and their new paths and values.
paths and values, or build the update document out of the new
paths and values.
new name was not already added in the background. We check
this as well now.
e.g. key2 → key3, key1 → key2 (or similar add/remove situations).
to extract their keys in the hadron-document API for hopefully
a bit more API clarity.
nested documents. This is the way that sharding behaves,
which is why we use them in the first place, and is not
a practical API to break. (And if it does, there is an
upcoming server sharding project will hopefully already have
made inclusion of the shard keys unnecessary.)
This also addresses COMPASS-5528 (which is about adjusting the
update document sent to the server, whereas COMPASS-5805 is about
adjusting the query document).
Description
Checklist
Motivation and Context
Open Questions
Dependents
Types of changes