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

Ability to de-select discriminator key #3230

Closed
vkarpov15 opened this issue Aug 4, 2015 · 10 comments
Closed

Ability to de-select discriminator key #3230

vkarpov15 opened this issue Aug 4, 2015 · 10 comments
Labels
confirmed-bug We've confirmed this is a bug in Mongoose and will fix it.
Milestone

Comments

@vkarpov15
Copy link
Collaborator

Re: #3133.

@vkarpov15 vkarpov15 added new feature This change adds new functionality, like a new method or class enhancement This issue is a user-facing general improvement that doesn't fix a bug or add a new feature labels Aug 4, 2015
@vkarpov15 vkarpov15 added this to the 5.0 milestone Aug 4, 2015
@Catatomik
Copy link

Any update or lead on this ?
I'd like to remove the __t field, note that I'm using the lean option.

And this is all about memory consumption ; __t field for a lot of documents represents a lot of memory.

@vkarpov15
Copy link
Collaborator Author

@Catatomik can you provide some code samples that show what you're trying to achieve?

@Catatomik
Copy link

@Catatomik can you provide some code samples that show what you're trying to achieve?

Of course, here's a short code sample :

const dbScheduledRoutes = await TBMScheduledRoutesModel.find<DocumentType<ScheduledRoute>>({}, dbScheduledRoutesProjection)
      .sort({ _id: 1 })
      .populate("trips.schedules", { hor_app: 1, hor_estime: 1, _id: 0 })
      .lean()
      .exec()

My types are made with typegoose.
trips.schedules is Ref<dbTBM_Schedules_rt>[].

The important part is about schedules, which is a discriminator.
Short schemas :

@modelOptions({ options: { customName: TBMEndpoints.Schedules } })
export class dbTBM_Schedules extends TimeStamps {
  @prop({ required: true })
  public hor_theo!: Date;
}

@modelOptions({ options: { customName: TBMEndpoints.Schedules_rt } })
export class dbTBM_Schedules_rt extends dbTBM_Schedules {
  @prop({ required: true })
  public hor_app!: Date;

  @prop({ required: true })
  public hor_estime!: Date;
}

So when populating through .populate("trips.schedules", { hor_app: 1, hor_estime: 1, _id: 0 }), I'd like to keep only hor_app and hor_estime. I got to remove _id (well documented, this filed is the only exception where you can make an exclusion with an inclusion projection), but nothing about the __t field).

A possible solution would be making an exclusion projection only, and put __t in. Don't know if it would work, but I strongly prefer to keep an inclusion projection.

@vkarpov15 vkarpov15 modified the milestones: Parking Lot, 7.6.6 Nov 1, 2023
@vkarpov15 vkarpov15 added has repro script There is a repro script, the Mongoose devs need to confirm that it reproduces the issue and removed new feature This change adds new functionality, like a new method or class enhancement This issue is a user-facing general improvement that doesn't fix a bug or add a new feature backwards-breaking labels Nov 1, 2023
@vkarpov15
Copy link
Collaborator Author

@Catatomik you can also deselect __t in an inclusive projection. Mongoose will automatically strip out __t from the projection before sending it to MongoDB, and then strip out __t from the result. See the following script for a Mongoose example:

'use strict';
  
const mongoose = require('mongoose');

run().catch(err => console.log(err));

async function run() {
  await mongoose.connect('mongodb://127.0.0.1:27017/mongoose_test');
  const Test = mongoose.model('Test', mongoose.Schema({ name: String }));
  const D = Test.discriminator('D', mongoose.Schema({ prop: String }));

  await Test.deleteMany({});
  await D.create({ name: 'foo', prop: 'bar' });

  console.log(await D.findOne().select({ name: 1, prop: 1, _id: 0, __t: 0 })); // { name: 'foo', prop: 'bar' }, no __t
}

@vkarpov15 vkarpov15 removed this from the 7.6.6 milestone Nov 24, 2023
@vkarpov15 vkarpov15 removed the has repro script There is a repro script, the Mongoose devs need to confirm that it reproduces the issue label Nov 24, 2023
@Catatomik
Copy link

@Catatomik you can also deselect __t in an inclusive projection. Mongoose will automatically strip out __t from the projection before sending it to MongoDB, and then strip out __t from the result. See the following script for a Mongoose example:

'use strict';
  
const mongoose = require('mongoose');

run().catch(err => console.log(err));

async function run() {
  await mongoose.connect('mongodb://127.0.0.1:27017/mongoose_test');
  const Test = mongoose.model('Test', mongoose.Schema({ name: String }));
  const D = Test.discriminator('D', mongoose.Schema({ prop: String }));

  await Test.deleteMany({});
  await D.create({ name: 'foo', prop: 'bar' });

  console.log(await D.findOne().select({ name: 1, prop: 1, _id: 0, __t: 0 })); // { name: 'foo', prop: 'bar' }, no __t
}

Well I tried that :
When I append __t: 0 to the inclusion projection (here .populate("trips.schedules", { hor_app: 1, hor_estime: 1, _id: 0 })), I get the following error : MongoServerError: Cannot do inclusion on field hor_estime in exclusion projection.
Note that without this __t: 0, code works well.
I use mongoose@7.6.3.

It might be due to the population ? Or my Schema ?

@vkarpov15
Copy link
Collaborator Author

What is your discriminator key? Perhaps it is set to a different value than __t.

@Catatomik
Copy link

What is your discriminator key? Perhaps it is set to a different value than __t.

I don't think so...

{
  hor_app: "+275760-09-13T00:00:00.000Z",
  hor_estime: "+275760-09-13T00:00:00.000Z",
  __t: "TBM_Schedules_rt",
}

@vkarpov15
Copy link
Collaborator Author

Might be due to populate, we will check

@vkarpov15 vkarpov15 reopened this Nov 28, 2023
@vkarpov15 vkarpov15 added this to the 7.6.7 milestone Nov 28, 2023
@vkarpov15 vkarpov15 added needs repro script Maybe a bug, but no repro script. The issue reporter should create a script that demos the issue confirmed-bug We've confirmed this is a bug in Mongoose and will fix it. and removed needs repro script Maybe a bug, but no repro script. The issue reporter should create a script that demos the issue labels Nov 28, 2023
@vkarpov15
Copy link
Collaborator Author

Looks like it is due to populate(), the following throws Cannot do inclusion on field prop in exclusion projection

'use strict';

const mongoose = require('mongoose');

run().catch(err => console.log(err));

async function run() {
  await mongoose.connect('mongodb://127.0.0.1:27017/mongoose_test');
  const Test = mongoose.model(
    'Test',
    mongoose.Schema({ name: String, arr: [{ testRef: { type: 'ObjectId', ref: 'Test2' } }] })
  );

  const schema = mongoose.Schema({ name: String });
  const Test2 = mongoose.model('Test2', schema);
  const D = Test2.discriminator('D', mongoose.Schema({ prop: String }));


  await Test.deleteMany({});
  await Test2.deleteMany({});
  const { _id } = await D.create({ name: 'foo', prop: 'bar' });
  let test = await Test.create({ name: 'test', arr: [{ testRef: _id }] });

  console.log(await Test.findById(test._id).populate('arr.testRef', { name: 1, prop: 1, _id: 0, __t: 0 }));
}

@vkarpov15
Copy link
Collaborator Author

As a workaround, use .populate("trips.schedules", { hor_app: 1, hor_estime: 1, _id: 0, '-__t': 0 })

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

2 participants