首页 > 解决方案 > Mongoose 查询 - findByIdAndUpdate 覆盖其他嵌套字段

问题描述

// MODEL MONGOOSE

const programSchema = new mongoose.Schema({
  name: { type: String, default: "" },
  description: { type: String, default: "" },
  accommodation: {
    info: {
      offer: { type: String, default: "" },
      description: { type: String, default: "" },
      completed: { type: Boolean, default: false }
    },
    arrangement: {
      participant: { type: String, default: "" },
      bedroom: { type: String, default: "" },
      completed: { type: Boolean, default: false }
    }
  }
});

我的应用程序

我运行一次,它会更新。

Program.findByIdAndUpdate(pid, 
    { 
        $set: { 
            'accommodation.info.offer': "Yes", 
            'accommodation.info.description': "Something", 
        } 
    }
).then(() => Program.findById(pid)
        .then((program) => {
            console.log(program);
            done();
        }))
});

在我的第一个动作之后,我的数据如下所示:

{
    name: "",
    description: "",
    accommodation: {
        info {
            offer: "Yes",
            description': "Something"
            completed: false
        },
        arrangement {
            participant: "",
            bedroom': ""
            completed: false
        }
   }
}

我运行第二个操作,它更新但覆盖并重置上面的第一个:

Program.findByIdAndUpdate(pid, {
  $set: {
    "accommodation.arrangement.participant": "Tom",
    "accommodation.arrangement.bedroom": "Jones"
  }
}).then(() =>
  Program.findById(pid).then(program => {
    console.log(program);
    done();
  })
);

在我的第二次行动之后,我的数据如下所示:

{
    name: "",
    description: "",
    accommodation: {
        info {
            offer: "",          // why is this reset to an empty string ??
            description': ""    // why is this reset to an empty string ??
            completed: false
        },
        arrangement {
            participant: "Tom",
            bedroom': "Jones"
            completed: false
        }
   }
}

我不知道为什么findByIdAndUpdate重置/覆盖其他字段,而不是 $set!任何帮助表示赞赏。我需要在之后运行 .save()findByIdAndUpdate吗?我有什么选择吗?

  1. 我运行一次,它会更新。
  2. 我运行第二个操作它更新但覆盖并重置上面的第一个

--- 这是我的测试代码

const assert = require('assert');
const Program = require('../models/program');
describe('Accomodation nested documents update', () => {

    let program
    let pid
    beforeEach((done) => {
        program = new Program({
            name: "Sports",
            description: "sddsdsdsdsdsd"
        })
        program.save().then((savedProgram) => {
            pid = savedProgram.id;
            done();
        })
    })

    it('2. Update accomodation : INFO', (done) => {
        Program.updateOne({ _id: pid }, 
            { 
                $set: { 
                    'accommodation.info.offer': "Yes",
                    'accommodation.info.description': "Something", 
                } 
            }
        )
        .then(() => Program.findById(pid))
        .then((program) => {
            assert(program.accommodation.info.offer === "Yes")
            done();
        })
    });

    it('3. Update accomodation : ARRANGEMENTS', (done) => {
        Program.updateOne({ _id: pid },
            {
                $set: {
                    "accommodation.arrangement.participant": "Tom",
                    "accommodation.arrangement.bedroom": "Jones"
                }
            }
        )
        .then(() => Program.findById(pid))
        .then((program) => {
            assert(program.accommodation.arrangement.participant === "Tom");
            assert(program.accommodation.info.offer === "Yes");  // This test fails
            done();
        })
    });
});

该测试通过了第一次测试,第二次失败了

标签: mongodbmongoose

解决方案


推荐阅读