首页 > 解决方案 > Mongoose 更新记录数组中的嵌套对象

问题描述

我目前遇到一个问题,我正在尝试更新 Mongoose 记录中的嵌套数组。我的架构如下:

const customerSchema = new mongoose.Schema({
    kimCustomerId: {
      type: Number,
      required: true
    },      
    addresses: [
      {        
        created: Date,
        updated: Date,                     
        addressInfo: {
          type: { type: String },
          typeOfAddress: String,
          careOf: String,
          address: String,
          addressRow1: String,
          addressRow2: String,
          zipcode: String,
          city: String,
          countryCode: String,
          physicalAddressType: String,
          validFrom: Date,
          validTo: Date
        }
      }
    ],
.....

如您所见,每条记录的地址数组包含许多地址。我希望能够通过更新对象并更新特定数组对象内的 addressInfo 嵌套对象内的属性。这是我的查询:

const updated = await db.models.customers.findOneAndUpdate(
    {
      _id: customer._id,
      'addresses.addressId': addressData.addressId
    },
    { $set: { 'addresses.$': addressData } },
    { new: true }
  );

以及我通过以更新记录的对象的示例:

{
    addressId: officialAddressExists.addressId,
    addressInfo: {
      validTo: new Date().toISOString()
    }
 }

我想要发生的是,当我将此对象传递给架构方法时,我想通过值“kimCustomerId”和“addressId”(我工作正常)选择正确的地址,然后只更新“addressInfo”的值' 我已通过的嵌套对象并保持未通过的对象原样,在本例中为 'validTo' 字段,但它可以是任意数量的更新。它目前正在覆盖整个“addressInfo”nestedObject,所以我认为我也必须对该嵌套对象进行某种设置操作,但我不确定如何操作。有人能在这里指出我正确的方向吗?谢谢!

标签: javascriptmongodbmongoosefindoneandupdate

解决方案


There is no straight way to do this in query, you can do it in your client side, something like,

// Sample body request
let addressData = {
    addressId: 1,
    addressInfo: {
      validTo: new Date().toISOString(),
      typeOfAddress: "Home",
      address: "ABC"
    }
};

let set = {};
for (let key in addressData.addressInfo) {
    set["addresses.$.addressInfo." + key] = addressData.addressInfo[key];
}
console.log(set);

Pass set variable in to your query,

const updated = await db.models.customers.findOneAndUpdate(
    {
      _id: customer._id,
      'addresses.addressId': addressData.addressId
    },
    { $set: set },
    { new: true }
);

推荐阅读