Skip to content

fix(query): handle casting array filter paths underneath array filter paths with embedded discriminators #15388

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

vkarpov15
Copy link
Collaborator

Fix #15386

Summary

The issue in #15386 is that events.$[event].products.$[product].price updates don't quite work if products is a path on an embedded discriminator where the discriminator key is set in the event array filter.

To get that to work, we needed to first fix castArrayFilters() to handle this pattern when casting array filters, and then improve how we handle casting the update in castUpdate() (getEmbeddedDiscriminatorPath() changes).

Examples

@vkarpov15 vkarpov15 added this to the 8.14.2 milestone Apr 30, 2025
Copy link

@Copilot 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 fixes an issue with casting array filter paths that reference embedded discriminators, as described in #15386. Key changes include:

  • Adding and propagating a discriminator value map in castArrayFilters and getPath.
  • Updating getEmbeddedDiscriminatorPath to correctly handle starting indices when processing embedded discriminator paths.
  • Adding tests for the new pattern in update.castArrayFilters.test.js.

Reviewed Changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
test/helpers/update.castArrayFilters.test.js Added a new test validating proper casting of array filter paths with embedded discriminators.
lib/helpers/update/castArrayFilters.js Modified to build a discriminator value map and pass it to getPath for embedded discriminator casting.
lib/helpers/schema/getPath.js Updated the function signature to accept a discriminator value map and use it when traversing the schema.
lib/helpers/query/getEmbeddedDiscriminatorPath.js Adjusted the path splitting logic by introducing a startIndex to handle multiple embedded discriminators.
Comments suppressed due to low confidence (1)

lib/helpers/query/getEmbeddedDiscriminatorPath.js:32

  • [nitpick] Consider renaming 'startIndex' to something like 'discriminatorStartIndex' to more clearly indicate its purpose.
const originalSubpath = parts.slice(startIndex, i + 1).join('.');

@@ -8,7 +8,7 @@ const numberRE = /^\d+$/;
* @api private
*/

module.exports = function getPath(schema, path) {
module.exports = function getPath(schema, path, discriminatorValueMap) {
Copy link
Preview

Copilot AI Apr 30, 2025

Choose a reason for hiding this comment

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

Update the JSDoc for getPath to describe the new 'discriminatorValueMap' parameter to aid future maintainers.

Copilot uses AI. Check for mistakes.

@@ -33,6 +33,9 @@ function _castArrayFilters(arrayFilters, schema, strictQuery, updatedPathsByFilt
return;
}

// Map of embedded discriminator values set in the array filters
Copy link
Preview

Copilot AI Apr 30, 2025

Choose a reason for hiding this comment

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

[nitpick] Consider adding a comment to document the purpose and usage of the 'discriminatorValueMap' for clarity.

Suggested change
// Map of embedded discriminator values set in the array filters
// Map to store discriminator values for embedded documents in the array filters.
// This is used to handle cases where array filters target specific embedded document types.

Copilot uses AI. Check for mistakes.

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, some minor nitpicks.

@@ -17,7 +17,7 @@ const updatedPathsByArrayFilter = require('../update/updatedPathsByArrayFilter')
*/

module.exports = function getEmbeddedDiscriminatorPath(schema, update, filter, path, options) {
const parts = path.split('.');
const parts = path.indexOf('.') === -1 ? [path] : path.split('.');
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is this a performance optimization? Because i think .split() will always return a array with a value, even if separator is not found.

Comment on lines +29 to 30
const currentPath = cur;
cur = '';
Copy link
Collaborator

Choose a reason for hiding this comment

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

Instead of assigning a new value, how about just moving the cur = '' reassignment to the end of the block?

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.

Arrayfilters does not work with nested array with descriminator
2 participants