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

$addToSet misbehave - missing docs/information about behavior #11284

Closed
dor-benatia opened this issue Jan 27, 2022 · 6 comments
Closed

$addToSet misbehave - missing docs/information about behavior #11284

dor-benatia opened this issue Jan 27, 2022 · 6 comments
Labels
confirmed-bug We've confirmed this is a bug in Mongoose and will fix it.
Milestone

Comments

@dor-benatia
Copy link

i've stumbled across a weird problem with mongoose $addToSet in patch function,

i am running this code :

const y = await model.updateOne(
    { _id: '61e0327e3889426f21dbbe25' },
    {
        $addToSet: { links: ['test1', 'test2', 'test3'] },
    },
);

when looking at the object in the db i see links: ['a','b',test1', 'test2', 'test3' ] which correspond to $addToSet with $each operator as explained in these docs: https://docs.mongodb.com/manual/reference/operator/update/addToSet/#value-to-add-is-an-array

which should of added this array as single element.

I am seeing in the code the corresponding line that caused that : lib/types/array/ArrayWrapper.js line 82.

The thing is that it is written no-where in the docs, not even a one liner.

maybe i am missing something ?

mongoose version: 6.0.13

@IslandRhythms IslandRhythms added the confirmed-bug We've confirmed this is a bug in Mongoose and will fix it. label Jan 27, 2022
@IslandRhythms
Copy link
Collaborator

const mongoose = require('mongoose');

const testSchema = new mongoose.Schema({
    name: []
});

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

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

const entry = await Test.create({
    name: [1,2,3,4,5]
});

console.log(entry);

await Test.findOneAndUpdate({_id: entry._id}, {$addToSet: {name: [6,7,8,9,0]}});
console.log(await Test.find());
}

run();

@dor-benatia
Copy link
Author

@IslandRhythms - this is exactly the code the reveal the problem - thank you.

@vkarpov15 vkarpov15 added this to the 6.1.10 milestone Jan 30, 2022
@twhy
Copy link

twhy commented Feb 5, 2022

What if there's code mistakenly rely on this misbehavior?

vkarpov15 added a commit that referenced this issue Feb 5, 2022
@vkarpov15
Copy link
Collaborator

Right now, the way that Mongoose handles this case is that it adds $each unless you're using $addToSet on a nested array path. For example, the below code doesn't add $each because name is a nested array.

const mongoose = require('mongoose');

mongoose.set('debug', true);

const testSchema = new mongoose.Schema({
    name: [[]] // <-- Array of arrays of any type
});

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

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

  const entry = await Test.create({
    name: [1,2,3,4,5]
  });

  console.log(entry);

  await Test.findOneAndUpdate({_id: entry._id}, {$addToSet: {name: [6,7,8,9,0]}});
  console.log(await Test.find());
}

run();

We'll avoid adding $each for mixed arrays for v6.2.1 👍

vkarpov15 added a commit that referenced this issue Feb 5, 2022
@dor-benatia
Copy link
Author

@twhy - i think it will appear as a breaking change and if you choose to update to version 6.2.1 you should handle that since it is obviously a bug.

@twhy
Copy link

twhy commented Feb 6, 2022

@dor-benatia Agree.

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