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

Mongoose 6: findOne is removing unknown attributes before executing the query #10781

Closed
gabrielmoreira opened this issue Sep 24, 2021 · 4 comments
Milestone

Comments

@gabrielmoreira
Copy link

gabrielmoreira commented Sep 24, 2021

I have a Client model where the _id attribute has an alias like clientId.

In version 5 of mongoose, Client.findOne({ clientId: '1' }) returns the document.
In version 6 of mongoose, Client.findOne({ clientId: '1' }) returns null.
However, in version 6, Client.findOne({ _id: '1' }) returns the document.

The problem doesn't seem to be related to field aliases, but to any unknown attributes used in a query. My next comment includes sample code to reproduce the problem.

If this is indeed the new behavior, it can silently break many projects.

@IslandRhythms IslandRhythms added help This issue can likely be resolved in GitHub issues. No bug fixes, features, or docs necessary needs clarification This issue doesn't have enough information to be actionable. Close after 14 days of inactivity and removed help This issue can likely be resolved in GitHub issues. No bug fixes, features, or docs necessary labels Sep 27, 2021
@IslandRhythms
Copy link
Collaborator

With mongoose, when you create a schema, mongoose automatically adds an _id property to that schema. In the description you've given, it seems that you have a clientId property with type set to String. However, it is unclear if you overrode the _id property. Please provide a script that demonstrates your issue.

@gabrielmoreira
Copy link
Author

I probably said something wrong. I couldn't reproduce the situation I found in my project. But during my tests, I found a different one.

I found out that the findOne function is removing any unknown attributes from the query, before executing it.

findOne({ unknownField: '123' }); on mongoose 5 will query using this unknownField, but on mongoose 6 it will remove this field before executing the query.

Code (bug1.js):

const mongoose = require("mongoose");
mongoose.set('debug', true);

const ClientSchema = new mongoose.Schema({
  code: String,
});

const Client = mongoose.model("Client", ClientSchema, "clients");

async function main() {
  console.log('mongoose version', mongoose.version);
  console.log('');
  await mongoose.connect("mongodb://localhost/mongoose_" + mongoose.version.replace(/\./g, '_'));
  const code = `client-${new Date().toISOString()}`;
  try {
    console.log('create client', await Client.create({
      code,
    }));
    console.log('')

    const client1 = await Client.findOne({ code });
    console.log('client1 =', client1);
    console.log('client1.code =', client1?.code);
    console.log('')

    const client2 = await Client.findOne({ code, unknownField: 123 });
    console.log('client2 =', client2);
    console.log('client2.code', client2?.code);
    console.log('')
    
  } finally {
    await mongoose.disconnect();
  }
}

main();

mongoose 5 (DEBUG=*) - Expected behaviour:

➜  DEBUG=* node bug1.js
mongoose version 5.13.3

Mongoose: clients.insertOne({ _id: ObjectId("6152dde54545971ddee7f3d5"), code: 'client-2021-09-28T09:18:29.731Z', __v: 0}, { session: null })
create client {
  _id: 6152dde54545971ddee7f3d5,
  code: 'client-2021-09-28T09:18:29.731Z',
  __v: 0
}

  mquery findOne clients { code: 'client-2021-09-28T09:18:29.731Z' } { projection: {} } +0ms
Mongoose: clients.findOne({ code: 'client-2021-09-28T09:18:29.731Z' }, { projection: {} })
client1 = {
  _id: 6152dde54545971ddee7f3d5,
  code: 'client-2021-09-28T09:18:29.731Z',
  __v: 0
}
client1.code = client-2021-09-28T09:18:29.731Z

  mquery findOne clients { code: 'client-2021-09-28T09:18:29.731Z', unknownField: 123 } { projection: {} } +9ms
Mongoose: clients.findOne({ code: 'client-2021-09-28T09:18:29.731Z', unknownField: 123 }, { projection: {} })
client2 = null
client2.code undefined

mongoose 6 (DEBUG=*) - Wrong behaviour:

➜  DEBUG=* node bug1.js
mongoose version 6.0.7

Mongoose: clients.insertOne({ code: 'client-2021-09-28T09:25:57.372Z', _id: new ObjectId("6152dfa50f9d4a210491dfb7"), __v: 0}, { session: null })
create client {
  code: 'client-2021-09-28T09:25:57.372Z',
  _id: new ObjectId("6152dfa50f9d4a210491dfb7"),
  __v: 0
}

  mquery findOne clients { code: 'client-2021-09-28T09:25:57.372Z' } { projection: {} } +0ms
Mongoose: clients.findOne({ code: 'client-2021-09-28T09:25:57.372Z' }, { projection: {} })
client1 = {
  _id: new ObjectId("6152dfa50f9d4a210491dfb7"),
  code: 'client-2021-09-28T09:25:57.372Z',
  __v: 0
}
client1.code = client-2021-09-28T09:25:57.372Z

  mquery findOne clients { code: 'client-2021-09-28T09:25:57.372Z' } { projection: {} } +7ms
Mongoose: clients.findOne({ code: 'client-2021-09-28T09:25:57.372Z' }, { projection: {} })
client2 = {
  _id: new ObjectId("6152dfa50f9d4a210491dfb7"),
  code: 'client-2021-09-28T09:25:57.372Z',
  __v: 0
}
client2.code client-2021-09-28T09:25:57.372Z

@gabrielmoreira gabrielmoreira changed the title Mongoose 6: findOne using field alias does not work Mongoose 6: findOne is removing unknown attributes before executing the query Sep 28, 2021
@vkarpov15 vkarpov15 added this to the 6.0.9 milestone Sep 28, 2021
@Kuzzy
Copy link

Kuzzy commented Sep 28, 2021

The same issue is here #10763

@vkarpov15 vkarpov15 modified the milestones: 6.0.9, 6.0.10 Oct 4, 2021
@vkarpov15 vkarpov15 removed the needs clarification This issue doesn't have enough information to be actionable. Close after 14 days of inactivity label Oct 7, 2021
@vkarpov15
Copy link
Collaborator

We added back the strictQuery option for 6.0.10. If this behavior is causing issues for you, you can add the below code before defining any models or schemas to opt out:

mongoose.set('strictQuery', false);

I'm sorry for the inconvenience and confusion this issue caused.

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

No branches or pull requests

4 participants