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

Versioning does not work if the versionKey option for toObject is set to false when using insertMany #14344

Closed
2 tasks done
juona opened this issue Feb 9, 2024 · 4 comments
Closed
2 tasks done
Labels
confirmed-bug We've confirmed this is a bug in Mongoose and will fix it.
Milestone

Comments

@juona
Copy link

juona commented Feb 9, 2024

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.1.1

Node.js version

18.18.2

MongoDB server version

5

Typescript version (if applicable)

No response

Description

Quite a specific issue here...

Setting the schema option toObject to { versionKey: false } interferes with the versioning mechanism when Model.prototype.insertMany() is used. This affects optimisticConcurrency too.

Debug logs print:

Mongoose: mymodels.insertMany([ { name: 'x', _id: new ObjectId('65c6b71554b43144d136c12f') } ], {})

Using Model.prototype.create() works correctly:

Mongoose: mymodels.insertOne({ name: 'x', _id: ObjectId("65c6b745afcd1f760cc117ba"), __v: 0 }, {})

Not surprising since the logic for the two methods is deliberately completely separate. Just makes me wonder if there are more edge cases like this one? I.e. what are some other ways of inserting a new document into the database that might not be covered? Perhaps this is something worth looking into.

Steps to Reproduce

import mongoose from "mongoose";
import { MongoMemoryReplSet } from "mongodb-memory-server";

console.log("connecting...");

const mongoDbService = await MongoMemoryReplSet.create();
await mongoose.connect(mongoDbService.getUri());

console.log("connected!");

const schema = new mongoose.Schema(
  { name: String },
  // Could be `optimisticConcurrency` as well
  { versionKey: "__v", toObject: { versionKey: false } }
);

const Model = mongoose.model("MyModel", schema);

// Substituting this for `create()` fixes the problem
await Model.insertMany([{ name: "x" }]);

const doc = await Model.findOne();

console.log(doc.__v); // prints `undefined` when using `insertMany`, and `1` when using `create`

await mongoose.disconnect();

console.log("done!")

process.exit(0);

Expected Behavior

My reasoning is that I set toObject: { versionKey: false } because I don't wish to have this field in the output when I invoke toObject(). I don't believe it should affect the internal mechanics of the versioning feature though.

@donoftime2018
Copy link

https://mongoosejs.com/docs/guide.html#versionKey

According to the documentation, you shouldn't be putting versionKey inside toObject. You should put it in the Schema definition like

const schema = new mongoose.Schema(
  { name: String },
  // Could be `optimisticConcurrency` as well
  { versionKey: false } //defaults to __v 
);

@vkarpov15 vkarpov15 added this to the 8.1.3 milestone Feb 13, 2024
@vkarpov15 vkarpov15 added the has repro script There is a repro script, the Mongoose devs need to confirm that it reproduces the issue label Feb 13, 2024
@IslandRhythms
Copy link
Collaborator

const mongoose = require('mongoose');

const testSchema = new mongoose.Schema(
  { name: String },
  // Could be `optimisticConcurrency` as well
  { versionKey: "__v", toObject: { versionKey: false } }
);

const Test = mongoose.model("Test", testSchema);

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

  await Test.insertMany([{ name: 'x' }]);

  const doc = await Test.findOne();

  console.log(doc.__v);

  console.log('done');
}

run();

@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 Feb 13, 2024
@donoftime2018
Copy link

donoftime2018 commented Feb 14, 2024

@juona Does this solve your problem for now?

#!/usr/bin/env node
const mongoose = require('mongoose');

const testSchema = new mongoose.Schema(
  { name: String },
  // Could be `optimisticConcurrency` as well
  { versionKey: '__v' }
);

// testSchema.set('__v', false) //sets __v to 0 commented out or not

const Test = mongoose.model("Test", testSchema);

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

  await Test.insertMany([{ name: 'x' }]);

  const doc = await Test.findOne();

  console.log(doc.__v); // 0

  console.log('done');

  process.exit(0)
}

run();

@vkarpov15 vkarpov15 modified the milestones: 8.1.3, 8.1.4 Feb 15, 2024
@vkarpov15 vkarpov15 modified the milestones: 8.1.4, 8.1.3 Feb 16, 2024
@juona
Copy link
Author

juona commented Feb 16, 2024

@donoftime2018 Thanks for the help. This was not a burning issue, I just used Model.prototype.create() instead. I will give your method a try in case there is a real need to use insertMany (still on v7, you see, so this fix probably does not apply).

@vkarpov15 Thanks, swift as always!

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

4 participants