updateOne matches but doesn't update

I have been trying to figure this out for over two days now, and just do not understand the error (or lack of) that Mongo is giving me. I am using Node.js.

Here’s the query code:

const result = await db.updateOne(
                    { userId: "100", "guilds.$.guildId": "1" },
                    { 
                        $set: { 
                            "guilds.xp": 5,
                        },
                    },
                );

On printing the result, I can see the modifiedCount is 0 but the matchedCount is 1.

There is only one record in the database:
userId: “100”,
guilds: [
guildId: “1”,
level: 1,
xp: 1,
]

Why does this not work?

Just to note, changing the query as follows:

updateOne(
   { userId: "100", guilds: { $elemMatch: { guildId: { $eq: '1' } } } },
       { 
          $set: { 
             "guilds.$.xp": 5,
              },
       },
 );

Does update the database, however it deletes the array and replaces it with an empty Object named guilds

Hello @Calebt, Welcome to the MongoDB community forum,

First, you can not use $ in the query part, so this is an invalid query,

Second, your document does not look correct/valid JSON,

I am just predicting the below document you have in your database,

{
  "userId": "100",
  "guilds": [
    {
      "guildId": "1",
      "level": 1,
      "xp": 1
    }
  ]
}

You wanted to update the first matching element’s guilds.xp to 5 if userId is “100” and guildId is “1”, Your update query would be,

.updateOne(
  { 
    "userId": "100", 
    "guilds.guildId": "1" 
  },
  {
    "$set": {
      "guilds.$.xp": 5
    }  
  }
)

Playground

This is also a valid syntax to check the condition,

You need to take care of the below point and check by yourself,

  • The case-sensitivity matters so make sure the database name is correct in your connection, and the collection name is in your model declaration, fields/properties name in your schema and query, should be in exact same case that you have in your database.
  • Make sure the “userId”: “100” should be in string “100” not in number 100, both are different
  • Make sure the “guildId”: “1” should be in string “1” not in number 1, both are different

Thanks for the reply.

I tried this but it throws an error (can’t create field ‘guildId’ in element)

.updateOne(
{
“userId”: “100”,
“guilds.guildId”: “1”
},
{
“$set”: {
“guilds.$.xp”: 5
}
}
)

I have also tried the following:

updateOne(
   { _id: user._id },
          { $set: { 
                "guilds.xp": 5,
                        },
                    },
        );

With the above query, I have also tried using
"guilds.$.xp": 5

"guilds.0.xp": 5

"guilds.xp": 5

all produce the same result of matching one record but 0 being updated. I have tried using quotation marks around $set, there is no difference here.

After three days of trying to solve this, I am giving up on trying to use the mongoose schema to do this. I am now getting an error saying "Cannot create field ‘guildId’ in element. So for anyone else reading this, give up now and save yourself three days.

I created a new function that connects to the database using the MongoDB library, and update the database that way.