简体   繁体   English

Mongoose 更新嵌套子文档

[英]Mongoose updating nested subdocuments

I am trying to update sub documents with mongoose using the request.body without passing of the sub documents _id .我正在尝试使用request.body更新子文档 mongoose 而不传递子文档_id Updating works but mongoose is removing the _id from the sub documents.更新有效,但 mongoose 正在从子文档中删除_id

Assume the following schemas假设以下模式

// schemas.js
const mongoose = require('mongoose');

const motorSchema = new mongoose.Schema({
    type: String,
    volume: Number,
});

const carSchema = new mongoose.Schema({
    manufacturer: String,
    model: String,
    motors: [motorSchema],
});

const userSchema = new mongoose.Schema({
   username: String,
   email: String,
   cars: [carSchema]
});
const mongoose = require('mongoose');
// import schemas
const userSchema = require('userSchema');
const carSchema = require('carSchema');
const motorSchema = require('motorSchema');
// create models
const User = mongoose.model("User", userSchema);
const Car = mongoose.model("Car", carSchema);
const Motor = mongoose.model("Motor", motorSchema);

module.exports.updateCar = async function (request, response) {
    const condition = {
        _id: new mongoose.Types.ObjectId(request.body.userId),
        "cars._id": new mongoose.Types.ObjectIt(request.body.carId)
        };

    // Build object for partial update
    const set = {};
    for(let field in reqest.body){
        set[`cars.$.${field}`] = request.body[field];
    }

    const update = {
        $set = set;
    }

    User.findOneAndUpdate(condition, update, {new: true, overwrite: false},
        (error, user) => {
            if(error) {response.send(error)}
            response.json(user);
        }
}

The problem is that all my _id properties will be overwritten in the motors array.问题是我所有的_id属性都将在 motors 数组中被覆盖。 How can I force mongoose as default to not change the _id properties?如何强制 mongoose 默认不更改_id属性?

If I understand you correctly, the equivalent mongoDB syntax will use arrayFilters , so you can modify your query to use that as well:如果我理解正确,等效的 mongoDB 语法将使用arrayFilters ,因此您也可以修改查询以使用它:

For example:例如:

User.findOneAndUpdate(
  condition,
  {$set: {"cars.$[item].size": "large"}},
  {arrayFilters: [{"item._id": new mongoose.Types.ObjectIt(request.body.carId)}]}
)

See how it works on the playground exampleplayground 示例中查看它是如何工作的

According to this method, your code needs the arrayFilters in the options part and the $[<identifier>] in the $set part of the query:根据此方法,您的代码需要选项部分中的arrayFilters和查询的$set部分中的$[<identifier>]

const set = {};
    for(let field in reqest.body){
        set[`cars.$[item].${field}`] = request.body[field];
    }

    const update = {
        $set = set;
    }

    User.findOneAndUpdate(
        condition, 
        update, 
        {
            arrayFilters: [{"item._id": new mongoose.Types.ObjectIt(request.body.carId)}],
            new: true, overwrite: false
        },
        (error, user) => {
            if(error) {response.send(error)}
            response.json(user);
        }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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