Skip to content
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

Find query fails with an error when using discriminator key multiple times #13906

Closed
2 tasks done
jpl-ivengi opened this issue Sep 29, 2023 · 1 comment
Closed
2 tasks done
Labels
confirmed-bug We've confirmed this is a bug in Mongoose and will fix it.
Milestone

Comments

@jpl-ivengi
Copy link

jpl-ivengi commented Sep 29, 2023

Prerequisites

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

Mongoose version

6.12.0

Node.js version

18.18.0

MongoDB server version

4.4

Typescript version (if applicable)

5.2.2

Description

A specific search query fails in mongoose when using discriminated models.
I've checked using a much older version of mongoose (v5.9.15) which does not fail.

const query = {
  type: 'clickedLinkEvent',
  $or: [
    { type: 'clickedImageEvent' }
  ]
}

const result = await Event.find(query).exec();

The error generated is:

    Can't set discriminator key "type"

      at model.Query.set (node_modules/mongoose/lib/helpers/model/discriminator.js:143:15)
      at SchemaString.Object.<anonymous>.SchemaType._applySetters (node_modules/mongoose/lib/schematype.js:1170:20)
      at SchemaString.Object.<anonymous>.SchemaType.applySetters (node_modules/mongoose/lib/schematype.js:1195:16)
      at SchemaString.Object.<anonymous>.SchemaType._castForQuery (node_modules/mongoose/lib/schematype.js:1649:15)
      at SchemaString.Object.<anonymous>.SchemaString.castForQuery (node_modules/mongoose/lib/schema/string.js:687:15)
      at SchemaString.Object.<anonymous>.SchemaType.castForQueryWrapper (node_modules/mongoose/lib/schematype.js:1613:20)
      at cast (node_modules/mongoose/lib/cast.js:342:32)
      at cast (node_modules/mongoose/lib/cast.js:71:18)
      at model.Query.Object.<anonymous>.Query.cast (node_modules/mongoose/lib/query.js:5351:12)
      at model.Query.Object.<anonymous>.Query._castConditions (node_modules/mongoose/lib/query.js:2229:10)
      at model.Query.<anonymous> (node_modules/mongoose/lib/query.js:2256:8)
      at model.Query._wrappedThunk [as _find] (node_modules/mongoose/lib/helpers/query/wrapThunk.js:29:8)
      at node_modules/kareem/index.js:497:25

Steps to Reproduce

The below code is typescript, using jest and chai with mongoose.

import {describe, test} from '@jest/globals';
import { model, Schema } from "mongoose";
import chai from 'chai';

const { expect } = chai;

describe('mongoose package', () => {
  test(`discriminators`, async () => {
    const options = { discriminatorKey: 'type' };

    interface IEvent  {
      type: string;
    }

    const eventSchema = new Schema({date: Schema.Types.Date}, options);
    const Event = model<IEvent>('Event', eventSchema, );

    interface IClickedLinkEvent extends IEvent {
      url: string;
    }

    const clickedLinkEventSchema = new Schema({ url: String }, options);
    const ClickedLinkEvent = Event.discriminator<IClickedLinkEvent>('ClickedLinkEvent', clickedLinkEventSchema, 'clickedLinkEvent');

    interface IClickedImageEvent extends IEvent {
      image: string;
    }

    const clickedImageEventSchema = new Schema({ image: String}, options);
    const ClickedImageEvent = Event.discriminator<IClickedImageEvent>('ClickedImageEvent', clickedImageEventSchema, 'clickedImageEvent');


    const clickedLinkEvent = new ClickedLinkEvent({ url: 'https://clicked-link.com' });
    expect(clickedLinkEvent.type).to.equal('clickedLinkEvent');
    expect(clickedLinkEvent.url).to.equal('https://clicked-link.com');

    const clickedImageEvent = new ClickedImageEvent({ image: 'clicked-image.png'});
    expect(clickedImageEvent.type).to.equal('clickedImageEvent');
    expect(clickedImageEvent.image).to.equal('clicked-image.png');

    const query = {
      type: 'clickedLinkEvent',
      $or: [
        { type: 'clickedImageEvent' }
      ]
    }

    const result = await Event.find(query).exec();
    expect(result.length).to.equal(0);
  }, 10000);
})

Expected Behavior

This should not be a failure. The query is written a bit strange ofcourse, but it is valid and should not be a reason for an error.

@jpl-ivengi jpl-ivengi changed the title Find query error when using discriminator key multiple times Find query fails with an error when using discriminator key multiple times Sep 29, 2023
@vkarpov15 vkarpov15 added this to the 7.5.5 milestone Oct 1, 2023
@vkarpov15 vkarpov15 added the has repro script There is a repro script, the Mongoose devs need to confirm that it reproduces the issue label Oct 1, 2023
@IslandRhythms IslandRhythms added confirmed-bug We've confirmed this is a bug in Mongoose and will fix it. and removed has repro script There is a repro script, the Mongoose devs need to confirm that it reproduces the issue labels Oct 2, 2023
@IslandRhythms
Copy link
Collaborator

const mongoose = require('mongoose');

const { Schema } = mongoose;

async function run() {
  await mongoose.connect('mongodb://127.0.0.1:27017');
  await mongoose.connection.dropDatabase();

  const options = { discriminatorKey: 'type' };

  const eventSchema = new Schema({date: Schema.Types.Date}, options);
    const Event = mongoose.model('Event', eventSchema, );


    const clickedLinkEventSchema = new Schema({ url: String }, options);
    const ClickedLinkEvent = Event.discriminator('ClickedLinkEvent', clickedLinkEventSchema, 'clickedLinkEvent');


    const clickedImageEventSchema = new Schema({ image: String}, options);
    const ClickedImageEvent = Event.discriminator('ClickedImageEvent', clickedImageEventSchema, 'clickedImageEvent');


    const clickedLinkEvent = new ClickedLinkEvent({ url: 'https://clicked-link.com' });
    console.log(clickedLinkEvent.type === 'clickedLinkEvent')
    // expect(clickedLinkEvent.type).to.equal('clickedLinkEvent');
    console.log(clickedLinkEvent.url === 'https://clicked-link.com')
    // expect(clickedLinkEvent.url).to.equal('https://clicked-link.com');

    const clickedImageEvent = new ClickedImageEvent({ image: 'clicked-image.png'});
    console.log(clickedImageEvent.type == 'clickedImageEvent')
    // expect(clickedImageEvent.type).to.equal('clickedImageEvent');
    console.log(clickedImageEvent.image == 'clicked-image.png')
    // expect(clickedImageEvent.image).to.equal('clicked-image.png');

    const query = {
      type: 'clickedLinkEvent',
      $or: [
        { type: 'clickedImageEvent' }
      ]
    }

    const result = await Event.find(query).exec();
    console.log(result.length == 0);
    // expect(result.length).to.equal(0);
}
run();

vkarpov15 added a commit that referenced this issue Oct 5, 2023
Island rhythms/gh 13906 handle changing discrim key
@vkarpov15 vkarpov15 modified the milestones: 7.6.1, 7.6.0 Oct 6, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
confirmed-bug We've confirmed this is a bug in Mongoose and will fix it.
Projects
None yet
Development

No branches or pull requests

3 participants