【问题标题】:How to overwrite one field of a schema with another in mongodb如何在mongodb中用另一个覆盖模式的一个字段
【发布时间】:2021-12-10 08:19:31
【问题描述】:

如何用updateLyric的值覆盖officialLyric的值??

artist: { type: String, required: true },
title: { type: String, required: true },
officialLyric: { type: String, required: true },
editedLyrics: [
  {
    updatedLyric: String,
    status: {
      type: String,
      enum: ["Aproved", "Rejected", "Pending"],
      default: "Pending",
    },
    userId: { type: Schema.Types.ObjectId, required: true, ref: "User" },
  },
],
releaseDate: { type: Date },

查看图片以清楚地描述问题。

enter image description here

【问题讨论】:

  • 属性updatedLyric在数组editedLyrics中,表示会有多个元素,officialLyric中应该更新哪个元素的值?
  • 是的,editedLyrics 数组可以容纳许多持有updatedLyric 的对象,所以我希望任一updatedLyric 来更新officialLyric

标签: node.js mongodb mongoose schema backend


【解决方案1】:

您可以从 MongoDB 4.2 开始尝试update with aggregation pipeline

  • $arrayElemAteditedLyrics 数组中获取updatedLyric 的第一个值并将其更新为officialLyric
db.collection.updateMany(
  {}, // put your query
  [{
    $set: {
      officialLyric: {
        $arrayElemAt: ["$editedLyrics.updatedLyric", 0]
      }
    }
  }]
)

Playground

【讨论】:

  • 我假设这里的0 ["$editedLyrics.updatedLyric", 0] 是表示数组的第一个值?那么是否可以根据 updatedLyric 的位置使用 1, 2 ... 或者它仅适用于数组中的第一个?
  • 是的,它是数组中元素的索引位置,你可以给出任何可用的索引号。
  • 这就像魔术感谢@turivishal,在我用它覆盖官方歌词后是否可以删除更新的歌词?谢谢:)
  • 是否可以删除 updatedLyric => 特定元素的 updatedLyric 属性或所有元素属性?
  • 如果可以的话,如果您能同时给我看,我将不胜感激。否则我想摆脱那个在editedLyrics数组中保存updatedLyric的特定对象,它刚刚覆盖了officialLyric
【解决方案2】:

如果您希望始终在 officialLyric 中的editedLyric 数组中获取最新 updateLyric 的值,则不需要将 officialLyric 实际存储在 DB 中。您可以使用 mongoose 虚拟字段并从架构中删除 officialLyric。

LyricSchema.virtual('officialLyric').get(function () { 
    if(!this.editedLyrics.length) return null;
    return this.editedLyrics[this.editedLyrics.length-1].updatedLyric;
});

如果您仍想先存储官方歌词,然后用您保存的编辑版本覆盖它。你可以使用钩子。

LyricSchema.post('save', async(error, doc, next) => {
    if(doc.editedLyrics.length && doc.officialLyric != doc.editedLyrics[doc.editedLyrics.length-1].updatedLyric){
        doc.officialLyric = doc.editedLyrics[doc.editedLyrics.length-1].updatedLyric;
        await doc.save();
    }
    next();
});

【讨论】:

  • 这个想法是,officialLyric 将保存来自数据库的歌词,但是当用户认为有错误并且应该更新时,我想存储更改而不是自动更新 officialLyric在editedLyrics 数组中,如果我(管理员)认为这是很好的改变,我希望editedLyrics 数组中的updatedLyric 覆盖officialLyric。
  • 更新答案,你试试钩子。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-08-14
  • 2013-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-12
  • 1970-01-01
相关资源
最近更新 更多