2

This is the structure of objects in database. I need nested schemas because nested objects of the array could be updated in different time and I need to know if this happens.

const PublicationSchema = new Schema({
    id: String,
    data: String,
}, {timestamps: true, _id: false]);

const AuthorSchema = new Schema({
    id: String,
    publications: [PublicationSchema]
}, { timestamps: true, _id: false});

My thought process is if I find the element in the array set it

AuthorModel.findOneAndUpdate(
    {
        id: authorId,
        "publications.id": publicationId
    },
    { 
        $set: {"publications.$[pub]": theNewObject
    },
    {
        arrayFilters: [{ 'publication.id': publicationId }],
        new: true
    },

and I get this error:

 Updating the path 'publications.$[pub].updatedAt' would create a conflict at 'publications.$[pub]'

I want to mention that if I had:

const AuthorSchema = new Schema({
    id: String,
    publications: [Schema.Type.Mixed]
}, { timestamps: true, _id: false});

then my function is working without errors, but doesn't include the updatedAt field. So how to make this update work with nested schemas?

Note: even after reading Similar Question, Similar Question2 I can't understand why this error occurs.

Gerasimos Ragavanis
  • 361
  • 1
  • 3
  • 16

1 Answers1

0

As I am reading more and more the Similar Question, the only work around seems to be:

AuthorModel.findOneAndUpdate(
    {
        id: authorId,
        "publications.id": publicationId
    },
    { 
        $set: {
            "publications.$[pub].id": theNewObject.id,
            "publications.$[pub].title": theNewObject.title,
            "publications.$[pub].content": theNewObject.content
        }              
    },
    {
        arrayFilters: [{ 'publication.id': publicationId }],
        new: true
    }
}

This way you don't create the conflict of updatedAt. In my tests if you update an item of the array only this gets the new updatedAt.

Another workaround in case you work with big objects and you wouldn't like to set each field or you don't know in advance all the fields you will need to set in the nested objects is to set the schema of Authors as:

const AuthorSchema = new Schema({
    id: String,
    publications: [Schema.Type.Mixed]
}, { timestamps: true, _id: false});

and then before findOneAndUpdate:

theNewObject.updatedAt: new Date();

so you can still use:

"publications.$[pub]": theNewObject
Gerasimos Ragavanis
  • 361
  • 1
  • 3
  • 16