Why does Mongodb (nodejs + Mongoose) not update object property of a document?

Asked

Viewed 40 times

-1

I have a document (Mongodb data) from user who has a field tags that stores the tags already used by the user. It is an object array in the format {text: 'tag1', count: 0}. The problem is when updating the data the value of the properties of the objects remains the old ones, even if in the.log console it shows the new values.

Caught the specific user with: users.findOne({name: 'exemplo'})

Example 1: Works if I do this.

user.tags = []
await user.save()
//No caso, definindo as tags para um array vazio

Example 2: Works if I do this.

user.tags = [{text: 'tag1', count: 0}, {text: 'tag2', count: 0}]
await user.save()
// Colocando um array real, atualiza normalmente.

Example 3: DOESN’T WORK if I do so (the value remains 0 zero)

user.tags[0].count = 5
await user.save()
/** Se eu fizer um console.log(user.tags) depois que salvar o count da posição zero mostra como 5 (correto), mas no banco de dados continua 0, nao atualiza */
//Ou seja, no console.log mostra certo, mas no DB nao

Example 4: Only increment does not work if I do so (the value remains 0 zero)

// valor atual de user.tags = [{text: 'tag1', count: 0}, {text: 'tag2', count: 0}]
user.tags = [{text: 'tag1', count: 1}, {text: 'tag2', count: 0}, {text: 'tag3', count: 0}]
/** Repare que agora a tag1 tem o count como 1, antes era zero. E agora tem a tag3, nesse exemplo a tag3 é adicionada significando que esta funcionando, mas o count da tag1 continua como zero */
// Não entendo porque nao muda ja que estou colocando um novo array completo
await user.save()

The "solution" that I found was a gambiarra erasing all array and putting new. But so far I don’t understand why I need to delete to add the new array.

// solução na gambiarra
user.tags = []
user.tags = [{text: 'tag1', count: 1}, {text: 'tag2', count: 0}, {text: 'tag3', count: 0}]
await user.save()

Modelschema

const mongoose = require('mongoose')
mongoose.Promise = global.Promise

const modelSchema = new mongoose.Schema({
    name: { type: String, required: true, trim: true, min: 3},
    tags: { type: Array },
)

const modelName = 'users'

if (mongoose.connection && mongoose.connection.models[modelName]) {
    module.exports = mongoose.connection.models[modelName]
} else {
    module.exports = mongoose.model(modelName, modelSchema)
}

1 answer

-1


The Documents of Mongoose use setters to identify which fields of your document have changed, and optimize the update in the database to not send more than necessary.

If the count is not being updated in the database, it is because it does not have a Setter, probably stemming from how you stated this Schema/Model.

It is possible to manually mark that a field has been changed with the method markModified:

user.tags[0].count = 5;
user.markModified('tags');
await user.save();

But working with a Setter properly configured should be preferred.

For this, instead of simply declaring tags as being of the type Array, create a Schema specific to that property:

const TagSchema = new mongoose.Schema({
    text: { type: String },
    number: { type: Number },
);

const UserSchema = new mongoose.Schema({
    name: { type: String, required: true, trim: true, min: 3 },
    tags: { type: [TagSchema] },
);
  • added like this schema, has more fields, as password and other. But the main structure is this. How would this configuration in schema?

  • @Dhenysonjhean, see if the information I added helps you.

  • It helped yes, thank you very much. I didn’t know I could declare one schema within another.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.