简体   繁体   中英

Mongoose : Update a nested object in an array

I have this mongoose schema in my project :

const mongoose = require('mongoose');
const schema = mongoose.Schema;

var WebsiteModel = new schema({

    name: {
        type: String,
        required: true,
        unique: true,
        lowercase: true
    },

    createdOn: {
        type: String,
        required: true,
        default: Date.now
    },

    country: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'Countries',
        required: true
    },

    categories: [{

        category: {
            type: mongoose.Schema.Types.ObjectId,
            ref: 'Categories'
        },

        name: {
            type: String,
            required: true,
            lowercase: true,
        },

        path: {
            type: String,
            required: true
        },

        enabled: {
            type: Boolean,
            required: true,
            default: false
        },

        description: {
            type: String,
            required: true,
            default: false
        },
    }]
});

module.exports = mongoose.model('Websites', WebsiteModel);

I want to make sure that when i update or add a document in categories array, the name, the path and the category id must be unique. So here is what i tried :

editWebsiteCategory = (req, resp) => {
    var websiteId = req.params.websiteid;
    var categoryId = req.params.categoryid;
    var categoryDatas = { ...req.body };
    var condition = {
        _id: websiteId,
        'categories.name':{$ne:{categoryDatas.name}},
        'categories.path':{$ne:{categoryDatas.path}},
        'categories._id':{$ne:{categoryDatas._id}},
        'categories._id': categoryId
    };
    if (categoryId && websiteId) {
        websiteModel.findOneAndUpdate(condition,
            { $set: { 'categories.$': categoryDatas } },
            (err, result) => {
                if (err) {

                    resp.status(500).json({ msg: "Internal Server Error !" });
                }

                if (result) {
                    resp.status(200).json(result);
                }
            })
    }
    else {
        resp.status(500).json({ msg: "Internal Server Error !" });
    }
}

CategoryDatas is an object containing all the necessary properties to save a category. Its structutre is similar to the object document within categories array in WebsiteModel above.

When I run the method editWebsiteCategory , even if the name and the path specified correspond to another existing category, datas are saved in the database and no errors are returned. So at the end i have two categories or more with the same name and path. It is exactely what i do not want.

Can somebody help ? Thanks.

In mongo style, using '$' positional operator. Check out this link for details.

db.my_collection.update(
  {_id: ObjectId(document_id), my_array.1 : 1 },
  { $set: { "my_array.$.content" : "NEW content B" } }
)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM