Skip to content

feat(NODE-5241): add option to return modified document #3710

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

Merged
merged 13 commits into from
Jun 21, 2023
Merged

Conversation

durran
Copy link
Member

@durran durran commented Jun 7, 2023

Description

Adds a new option to the findOneAnd... family of methods, includeResultMetadata which defaults to true. When set to the default, it will return a ModifyResult, when set to false, it will return the actual modified document.

What is changing?

  • Adds the includeResultMetadata option.
  • Update the types of findOneAndReplace, findOneAndDelete, findOneAndUpdate.
  • Adds new type tests.
  • Refactors crud api tests and find and modify tests to use async/await.
  • Removes redundant tests.
Is there new documentation needed for these changes?

Yes

What is the motivation for this change?

NODE-5241

Release Highlight

New includeResultMetadata option for findOneAnd... family of methods.

This option defaults to true, which will return a ModifyResult type. When set to false, which will
become the default in the next major release, it will return the modified document or null if nothing matched.
This applies to findOneAndDelete, findOneAndUpdate, findOneAndReplace.

// With a document { _id: 1, a: 1 } in the collection
await collection.findOneAndDelete({ a: 1 }, { includeResultMetadata: false }); // returns { _id: 1, a: 1 }
await collection.findOneAndDelete({ a: 2 }, { includeResultMetadata: false }); // returns null
await collection.findOneAndDelete({ a: 1 }, { includeResultMetadata: true }); // returns { ok: 1, lastErrorObject: { n: 1 }, value: { _id: 1, a: 1 }}

Double check the following

  • Ran npm run check:lint script
  • Self-review completed using the steps outlined here
  • PR title follows the correct format: type(NODE-xxxx)[!]: description
    • Example: feat(NODE-1234)!: rewriting everything in coffeescript
  • Changes are covered by tests
  • New TODOs have a related JIRA ticket

Sorry, something went wrong.

@durran durran changed the title Node 5241 feat!(NODE-5241): return raw result by default with find and modify Jun 7, 2023
@@ -29,6 +29,8 @@ export interface FindOneAndDeleteOptions extends CommandOperationOptions {
sort?: Sort;
/** Map of parameter names and values that can be accessed using $$var (requires MongoDB 5.0). */
let?: Document;
/** Return the raw result document instead of the ModifyResult */
returnRawResult?: boolean;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just wanted to bring a couple of points to your attention from the ticket description so that we minimize potential back and forth in review:

Dev note: returnRawResult is not meant to be prescriptive - the server returns a write_ops::FindAndModifyCommandReply, internally the driver returns a ModifyResult but our flag should make it clearer as to what is being returned

API docs should clearly explain the option

It may be worth taking this back to the team for consensus on option name; once the option name is settled, it's important to make sure we set accurate expectations for what the option does. The spec compliant version of these commands returns less information than the current ModifyResult. In the original ticket, returnRawResult = true is intended to return what is currently ModifyResult and returnRawResult = false is intended to return the spec compliant version, which is equal to ModifyResult.value.

@durran durran force-pushed the NODE-5241 branch 4 times, most recently from 9a3664c to 7b75770 Compare June 12, 2023 13:07
/**
* Test findOneAndUpdate a document
*/
it('shouldCorrectlyfindOneAndUpdateDocument', {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The cases in this giant test case are covered in individual findAndModify tests as well as spec tests.

/**
* Test findOneAndUpdate a document
*/
it('Should Correctly Handle findOneAndUpdate Duplicate Key Error', {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was testing server behaviour.

@durran durran marked this pull request as ready for review June 12, 2023 16:21
@baileympearson baileympearson changed the title feat!(NODE-5241): return raw result by default with find and modify feat(NODE-5241): return raw result by default with find and modify Jun 12, 2023
@durran durran changed the title feat(NODE-5241): return raw result by default with find and modify feat!(NODE-5241): add option to return modified document Jun 12, 2023
metadata: {
requires: { topology: ['single', 'replicaset', 'sharded', 'ssl', 'heap', 'wiredtiger'] }
},
test: async function () {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think all of these topology requirements are no longer necessary. Do you want to remove the metadata block entirely?

(same is true for all tests I think)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed.


findOneAndReplace();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just want to comment on this ... recursive test functions? wow. 🙁

@@ -127,6 +135,41 @@ expectAssignable<SchemaWithIdNumberInterface | null>(
(await interfaceNumberTestCollection.findOneAndUpdate({ a: 1 }, { a: 5 })).value
);

expectAssignable<SchemaWithIdNumberType | null>(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without helpful errors / describe blocks / test names, it's hard to GROK what these tests are testing. I think they're testing the return type of findOneAnd* methods when includeResultMetadata is false?

  1. should these tests live in findX.test-d.ts? They're not actually related to how we infer the collection schema (which is that this file is for I think)
  2. can we comment them to make it clear what they're testing? Something I've considered in the past is an anonmyous scope with a comment:
// findOneAnd* methods return the modified document when `includeResultMetadata` is false
{ 
	expectAssignable<SchemaWithIdNumberInterface | null>(
  		await interfaceNumberTestCollection.findOneAndDelete({ a: 1 }, { includeResultMetadata: false })
	);
   
	...
} 

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've reverted the schema_helpers.test-d.ts changes per your comment, and simplified type testing by just adding 3 tests (1 for each method) in findX-test-d.ts and added a comment to them.

@dariakp dariakp changed the title feat!(NODE-5241): add option to return modified document feat(NODE-5241): add option to return modified document Jun 12, 2023
@dariakp dariakp added the Primary Review In Review with primary reviewer, not yet ready for team's eyes label Jun 12, 2023
@durran durran force-pushed the NODE-5241 branch 2 times, most recently from 4cf8db6 to 33023ff Compare June 15, 2023 13:13
@durran durran requested a review from baileympearson June 15, 2023 18:28
import { expect } from 'chai';

import { type CommandStartedEvent, MongoServerError, ObjectId } from '../../mongodb';
import { setupDatabase } from '../shared';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have any tests for includeResultMetadata = false? I see tests for the default behavior, but nothing with includeResultMetadata disabled.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added tests with the option set to false.

baileympearson
baileympearson previously approved these changes Jun 20, 2023
@nbbeeken nbbeeken added Team Review Needs review from team and removed Primary Review In Review with primary reviewer, not yet ready for team's eyes labels Jun 20, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Team Review Needs review from team
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants