Skip to content

Conversation

@AbdelrahmanHafez
Copy link
Collaborator

@AbdelrahmanHafez AbdelrahmanHafez commented Nov 18, 2025

Adds a global option for updatePipeline for convenience
Fixes #15756, re #15728 (comment)

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR adds a global updatePipeline option to Mongoose, allowing developers to enable update pipelines (array-based updates) by default without needing to specify updatePipeline: true on each individual query. This addresses issue #15756 and aligns with Mongoose 9's breaking change that requires explicit opt-in for update pipelines.

Key Changes:

  • Added global updatePipeline configuration option that defaults to false
  • Implemented option inheritance in query methods (updateOne, updateMany, findOneAndUpdate, findOneAndReplace, findByIdAndUpdate)
  • Query-level options can override the global setting

Reviewed Changes

Copilot reviewed 6 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
types/mongooseoptions.d.ts Adds TypeScript type definition for the new updatePipeline global option
test/types/base.test.ts Adds TypeScript tests to verify the option can be set via mongoose.set()
lib/validOptions.js Registers updatePipeline as a valid Mongoose option and maintains alphabetical ordering
lib/query.js Implements global option inheritance in findOneAndUpdate, findOneAndReplace, and _update helper
lib/mongoose.js Documents the new global option in the JSDoc for mongoose.set()
docs/migrating_to_9.md Adds migration guide documentation with examples of using the global option
test/model.test.js Comprehensive test suite covering global option behavior, overrides, and various update methods

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

lib/query.js Outdated
Comment on lines 3724 to 3727
const updatePipeline = this?.model?.base?.options?.updatePipeline;
if (options.updatePipeline == null && updatePipeline != null) {
options.updatePipeline = updatePipeline;
}
Copy link

Copilot AI Nov 18, 2025

Choose a reason for hiding this comment

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

The global updatePipeline option is applied after _mergeUpdate() is called (line 3714), but _mergeUpdate() checks this._mongooseOptions.updatePipeline to determine whether array updates are allowed. This means the global option won't take effect for findOneAndReplace().

The correct order should be:

  1. Apply global option to options object
  2. Call this.setOptions(options) (which sets this._mongooseOptions.updatePipeline)
  3. Call this._mergeUpdate(replacement)

This is the order used in findOneAndUpdate() (lines 3459-3468) and should be followed here as well.

Copilot uses AI. Check for mistakes.
Copy link
Collaborator

Choose a reason for hiding this comment

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

I fixed this by removing updatePipeline for findOneAndReplace() since findOneAndReplace can't use update pipelines anyway

Copy link
Collaborator

@hasezoey hasezoey left a comment

Choose a reason for hiding this comment

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

LGTM, but copilot has some points.

@vkarpov15 vkarpov15 merged commit b962408 into 9.0 Nov 19, 2025
67 checks passed
@AbdelrahmanHafez AbdelrahmanHafez deleted the gh-15756 branch November 19, 2025 11:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] global updatePipeline option

4 participants