Skip to content

Arrayfilters does not work with nested array with descriminator #15386

Closed
@emmet-opinionx

Description

@emmet-opinionx

Prerequisites

  • I have written a descriptive issue title
  • I have searched existing issues to ensure the bug has not already been reported

Mongoose version

8.14.1

Node.js version

20.18.0

MongoDB server version

5

Typescript version (if applicable)

No response

Description

If you have a array of documents on a discriminated schema array. mongoose fails to find the correct schema when casting array filters

Steps to Reproduce

The following throws error Could not find path "events.0.products.0._id" in schema

  const eventSchema = new Schema(
    { message: String },
    { discriminatorKey: 'kind', _id: false },
  );

  const batchSchema = new Schema({ events: [eventSchema] });

  // `batchSchema.path('events')` gets the mongoose `DocumentArray`
  // For TypeScript, use `schema.path<Schema.Types.DocumentArray>('events')`
  const docArray = batchSchema.path<Schema.Types.DocumentArray>('events');

  // The `events` array can contain 2 different types of events, a
  // 'clicked' event that requires an element id that was clicked...
  const clickedSchema = new Schema(
    {
      element: {
        type: String,
        required: true,
      },
    },
    { _id: false },
  );
  // Make sure to attach any hooks to `eventSchema` and `clickedSchema`
  // **before** calling `discriminator()`.
  docArray.discriminator('Clicked', clickedSchema);

  const productSchema = new Schema({
    name: { type: String },
    price: { type: Number },
  });

  // ... and a 'purchased' event that requires the product that was purchased.
  docArray.discriminator(
    'Purchased',
    new Schema({
      products: {
        type: [productSchema],
        required: true,
      },
    }),
  );

  const Batch = db.model('EventBatch', batchSchema);

  const purchasedId = new mongoose.Types.ObjectId();
  const productId = new mongoose.Types.ObjectId();

  const doc = await Batch.create({
    events: [
      { kind: 'Clicked', element: '#hero', message: 'hello' },
      {
        kind: 'Purchased',
        _id: purchasedId,
        products: [{ name: 'productName1', price: 10, _id: productId }],
        message: 'world',
      },
    ],
  });

  console.log('Result', doc);

  const updatedBatch = await Batch.findByIdAndUpdate(
    doc._id,
    {
      'events.$[event].products.$[product].price': 20,
    },
    {
      arrayFilters: [
        {
          'event._id': purchasedId,
          'event.kind': 'Purchased', // Does not work with or without this
        },
        { 'product._id': productId },
      ],
      new: true,
    },
  ).exec();

Expected Behavior

Should be able to use arrayFilters to update an array on nested array of a discriminated schema

Metadata

Metadata

Assignees

No one assigned

    Labels

    confirmed-bugWe've confirmed this is a bug in Mongoose and will fix it.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions