1
Messages.update(
    {_id: docId, "messages.senderId": friendId},
    {
        $set: {"messages.$[elem].read": true}
    },
    {
        multi: true,
        arrayFilters: [{"elem.senderId": friendId}]
    },
    (err, result) => {
        if (err) {
            return res.status(500).json({message: "Something error occured" + err})
        } else {
            return res.status(200).json({message: "Successfully", result})
        }
    }
)

when this command execute I get an error.

Could not find path "messages.0.senderId" in schema" and my schema is

const Schema = new mongoose.Schema({
    conversations: Array,
    messages: Array
})

How can solve this problem?, please, help me.

i follow this solution but not work.

Tom Slabbaert
  • 21,288
  • 10
  • 30
  • 43
hydraCode
  • 77
  • 10

2 Answers2

2

This is a moongoose error as your schema does not specify the complete structure. You can see here that the Mongo update syntax is working as expected.

It seems this is a missing feature for now, As seen in the source code (mongoose v6)

if (schematype == null) {
  if (!strictQuery) {
    return;
  }
  // For now, treat `strictQuery = true` and `strictQuery = 'throw'` as
  // equivalent for casting array filters. `strictQuery = true` doesn't
  // quite work in this context because we never want to silently strip out
  // array filters, even if the path isn't in the schema.
  throw new Error(`Could not find path "${filterPath}" in schema`);
}

The comment acknowledges this bad behaviour, but this is still the logic used even for "mixed type" arrays.

You can either:

  1. Update your Array schema to fully describe the object:
const Schema = new mongoose.Schema({
    conversations: Array,
    messages: [{senderId: String}]
})
  1. Pass the strict: false option in the update, this will also disable other validations which means it's the less preferable approach:
Messages.update(
    {_id: docId, "messages.senderId": friendId},
    {
        $set: {"messages.$[elem].read": true}
    },
    {
        multi: true,
        strict: false,
        arrayFilters: [{"elem.senderId": friendId}]
    },
    (err, result) => {
        if (err) {
            return res.status(500).json({message: "Something error occured" + err})
        } else {
            return res.status(200).json({message: "Successfully", result})
        }
    }
)
Tom Slabbaert
  • 21,288
  • 10
  • 30
  • 43
  • but, Brother it is give error during save messages in db after configuration Schema. My configuration for save messages in db. `const message = await Messages( { conversations: [req.body.adminId, req.body.friend_id], messages: {message: messageChange,time: req.body.time,senderId: req.body.adminId, type: req.body.type, messageID: req.body.messageID, read: req.body.seen }}) message.save()` – hydraCode Jul 03 '22 at 12:37
  • did you add all the relevant fields to the schema? not just senderId – Tom Slabbaert Jul 03 '22 at 12:40
  • yes, ` new mongoose.Schema({ conversations: Array, messages: [{ message: String, senderId: String, type: String, messageID: String, read: Boolean, time:{ type: String, default: Date.now() } }], })` – hydraCode Jul 03 '22 at 12:42
  • and give this kind of error,, ValidationError: messages.0: Cast to [string] failed for value \"[\\n' +\n ' {\\n' +\n \" message: 'gek',\\n\" +\n ' time: 1656852475119,\\n' +\n \" senderId: '62bb59979690362946aedb02',\\n\" +\n \" type: 'text',\\n\" +\n ' messageID: 163172,\\n' +\n ' read: false\\n' +\n ' }\\n' +\n ']\" (type string) at path \"messages.0\"","messageId":163172} – hydraCode Jul 03 '22 at 12:48
  • help me brother – hydraCode Jul 03 '22 at 13:06
  • It seems like it's just a schema type mismatch. ("cast to string failed" ), just make sure if you defined "String" in the schema that the input is also string – Tom Slabbaert Jul 03 '22 at 13:35
  • yes, I defined both side but still same error exits. – hydraCode Jul 03 '22 at 15:10
  • it is work. when `conversations: Array, messages: [{message: { type: String },time: { type: String },senderId: { type: String },type: { type: String }, }],` when defined Schema in this type – hydraCode Jul 03 '22 at 15:56
1

This is a moongoose error as your schema does not specify the complete structure. You can see here that the Mongo update syntax is working as expected.

It seems this is a missing feature for now, As seen in the source code (mongoose v6)

if (schematype == null) {
  if (!strictQuery) {
    return;
  }
  // For now, treat `strictQuery = true` and `strictQuery = 'throw'` as
  // equivalent for casting array filters. `strictQuery = true` doesn't
  // quite work in this context because we never want to silently strip out
  // array filters, even if the path isn't in the schema.
  throw new Error(`Could not find path "${filterPath}" in schema`);
}

The comment acknowledges this bad behaviour, but this is still the logic used even for "mixed type" arrays.

You can either:

  1. Update your Array schema to fully describe the object:
const Schema = new mongoose.Schema({
    conversations: Array,
    messages: [{senderId: String, read: Boolean}]
})
  1. Pass the strict: false option in the update, this will also disable other validations which means it's the less preferable approach:
Messages.update(
    {_id: docId, "messages.senderId": friendId},
    {
        $set: {"messages.$[elem].read": true}
    },
    {
        multi: true,
        strict: false,
        arrayFilters: [{"elem.senderId": friendId}]
    },
    (err, result) => {
        if (err) {
            return res.status(500).json({message: "Something error occured" + err})
        } else {
            return res.status(200).json({message: "Successfully", result})
        }
    }
)
Tom Slabbaert
  • 21,288
  • 10
  • 30
  • 43