如何在mongodb中用另一个覆盖模式的一个字段

Posted

技术标签:

【中文标题】如何在mongodb中用另一个覆盖模式的一个字段【英文标题】:How to overwrite one field of a schema with another in 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 【参考方案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。 更新答案,你试试钩子。

以上是关于如何在mongodb中用另一个覆盖模式的一个字段的主要内容,如果未能解决你的问题,请参考以下文章

MongoDB:如何为集合中的每个文档设置一个等于另一个字段值的新字段[重复]

GoLang 中用 MongoDB Watch 监听指定字段的变化

如何根据另一个字段更新 mongodb 中的数组 dict 元素

如何检查数组字段是不是包含唯一值或 MongoDB 中的另一个数组?

如何使用 mongoose 和 NodeJs 在 Mongodb 的数组字段中插入数据

如何匹配 MongoDB 中的子文档数组?