graphql-compose / graphql-compose-mongoose

Mongoose model converter to GraphQL types with resolvers for graphql-compose https://github.com/nodkz/graphql-compose
MIT License
709 stars 94 forks source link

Array field UpdateMany - $set as object instead of $push array #402

Open meabed opened 2 years ago

meabed commented 2 years ago

Thank you so much ❤️ for all the great work and effort.

I have found a potential bug:

When you use updateMany resolver on array field it is executed on mongoose as $set.0 - $set.1 - .... and this result of the mongodb field data type to become Object instead of Array

For example

# mongoose 
const userSchema = new Schema(
  {
    companies: {
      type: [Schema.Types.ObjectId],
      ref: 'Company',
    }
});

schemaComposer.Mutation.addFields({
  userUpdateMany: userTC.mongooseResolvers.updateMany(),
});
# graphql
mutation updateUser {
  userUpdateMany(
    filter: { email: "email@email.com" }
    record: { companies: ["625b27bdada2c1e426941971", "625b27bdada2c1e426941971"] }
  ) {
    numAffected
  }
}
# the result query is like this
Mongoose: users.updateMany({ email: 'email@email.com' }, { '$setOnInsert': { createdAt: new Date("Sun, 17 Apr 2022 01:55:38 GMT") }, '$set': { 'companies.0': new ObjectId("625b27bdada2c1e426941971"), 'companies.1': new ObjectId("625b27bdada2c1e426941971"), updatedAt: new Date("Sun, 17 Apr 2022 01:55:38 GMT") }}, { limit: 100, multi: true })

So the companies field becomes object because it's first time set.

image

Ideally, updateMany should $set the whole array not the indexes. so the query should be like

users.updateMany({ '$set': { 'companies': [new ObjectId("625b27bdada2c1e426941971")] } });

Using UpdateOne works as expected - this issues is only with updateMany.