Can not update the object inside array

My schema:

import pkg from "mongoose";

const { Schema, model, models } = pkg;

const child = new Schema({ name: String, studentid: Number});
const schema = new Schema({ name: String, age: Number, children: [child] });

const Test = model("Test", schema) 

export default Test;

Data sample:

Sample data

My update function, I wish to update the entire object inside the array base on age and studentid:

import { connectToDB } from "./utils/database.js";
import Test from "./models/test.js";

async function updateData() {
  await connectToDB();

  const res = Test.updateMany(
    {
      age: 34,
      name: "name2",
    },
    {
      $set: {
        "children.$[element]": {
          name: "updatedname",
          studentid: 123456789,
        },
      },
    },
    {
      arrayFilters: [
        {
          element: {
            name: "childr344en1",
            studentid: 137,
          },
        },
      ],
    },
    {upsert: true}
  );
  console.log(res)
}

await updateData();

After executing the update function, the data didn’t update. May I ask why? Where am I doing wrong?

I tried to replicate what you’re doing in a local mongo instance and it seemed to work, unless anyone with better eyes than me can see a difference?

db.getCollection("Test").updateMany(
    {
      age: 34,
      name: "name2",
    },
    {
        $set:{
            'children.$[element]':{
              name: "updatedname",
              studentid: 123456789,
            }
        }
    },
    {
        arrayFilters:[
            {
                element:{
                    name: "childr344en1",
                    studentid: 137,            
                }
            }
        ]
    },
    {upsert:true}
)

What’s in the return object from the server? What does it report as the matched / modified counts?

Do you mean “res”, what key and value inside “res” should I look for? How can I get the matched/modified counts in above code? Thank you.

Actually you’re not awaiting the results of the execution, can you add an await:

  const res = await Test.updateMany(

2 Likes

It works, can you explain why not adding await will lead to fail update?

The call to mongo is async so it’ll exit the function without waiting for it to even be sent to the server, I imagine that the connection or client is disposed of at some point which happens before the query has been executed.
So if you had something like this (pseudocode):

const mongoCon = new mongoClient();
await mongoCon.open()
mongoCon.db.col.insertOnce({'a':'b'})
mongoCon.close()

The connection would close before the statement was executed, if you’re not seeing an error in the output it’s being thrown away somewhere.

Doing this would cause the statement to be executed though:

const mongoCon = new mongoClient();
await mongoCon.open()
const retVal = await mongoCon.db.col.insertOnce({'a':'b'})
mongoCon.close()

1 Like