Mongoose:无法将数据保存到空对象

Posted

技术标签:

【中文标题】Mongoose:无法将数据保存到空对象【英文标题】:Mongoose: Unable To Save Data To Empty Object 【发布时间】:2020-11-15 21:55:30 【问题描述】:

这是我的情况:

我有一个简单的 Schema,它有一个名为 commands 的对象,我最初将其设置为

commands:

当我将文档添加到数据库时,我遍历了一个命令文件,并通过执行command["command"] = "blah blah"; 将它们添加到对象中。我这样做的方式如下(我工作的代码很旧):

Guild.findOne(guildId:serverId).then(x=>
  x.commands = ;
  for(let command of Object.values(commandInfo))
    if(!command.name) continue;
    const getSubs = ()=>
      const subArray = ;
      if(!command.subCommands) return;
      for(let subs of Object.values(command.subCommands))
        subArray[subs.name] = 
          access:subs.access,
          disabled:subs.disabled
        
      
      x.commands[command.name].subCommands = subArray;
    
    x.commands[command.name] = 
      access:command.access,
      bounded:command.bounded,
      disabled:command.disabled,
    
    getSubs();
  
  console.log("Success!");
  x.save();
);

命令包含以下内容(我将使用两个命令作为示例):

work:
  access:"All",
  bounded:"A Channel",
  disabled:false
,
profile:
  access:"All",
  bounded:"Another Channel",
  disabled:false,
  subCommands:
    bio:
      access:"All",
      disabled:true
    
    register:
      access:"All",
      disabled:false
   
 

快进到现在,我制作了一个应该编辑这些命令的配置文件。我写的代码工作得很好;但是,Mongoose 无法保存命令的任何更改。除了与命令相关的任何内容外,我的 Schema 中的所有其他内容都可以在配置文件中使用。

我知道是什么问题。 Mongoose 在 Schema 中找不到命令并且不知何故感到困惑。而且我知道我可以通过将所有命令及其属性添加到 Schema 来修复它。唯一的问题是它很乏味,并且不是我添加任何新命令的干净解决方案。另外,我将命令的所有信息放在一个单独的文件中,所以我不想重写我已经写过的内容。

我的问题是:我的问题有解决方法吗?我尝试设置commands to Schema.Types.Mixed,但这并没有解决它。我也四处寻找类似的东西,但找不到任何东西。

这是所要求的完整架构:

const Schema, model = require("mongoose");
const settings = require("../utils/settings");

const guildSchema = Schema(
  guildId:String,
  symbols:
    prefix:type:String, default:";",
    currency:type:String, default:"$"
  ,
  channels:
    casinoChannels:Array,
    fineChannels:Array
  ,
  commands:Schema.Types.Mixed,
  hierarchy:[
    name:String,
    role:type:String, default:"",
    members:Array
  ],
  users:[
    userId:String,
    cash:Number,
    bank:Number,
    items:[
      name:String, 
      amount:Number
    ],
    timers:
      work:String,
      crime:String,
      hack:String,
      steal:String,
      daily:String,
      weekly:String,
      marry:String,
      divorce:String,
      idea:String,
      report:String,
      quiz:String
    ,
    fine:
      fineId:String,
      description:String,
      report:String,
      pay:Number
    ,
    used:String
  ],
);

guildSchema.virtual("addUser").set(function(id)
  const user = 
    userId:id,
    cash:settings.cash,
    bank:settings.bank
  ;

  this.users.push(user);
  return user;
);   

module.exports = model("Servers", guildSchema);

【问题讨论】:

代码的哪一部分将 guildId 存储到文档中?我在这里的任何地方都看不到公会ID @DeekshithHegde 刷新线程。我发布了完整的架构。 【参考方案1】:

使用findOneAndUpdate更新集合中的现有文档。

让你想在 mongodb 的“命令”中更新的对象在 x 变量中。

Guild.findOneAndUpdate(guildId : serverId,commands : x));

当找到匹配项时,您存储在x 变量中的对象将直接更新/替换为该新数据。

更新不完全替换现有对象

let guild = Guild.findOne(guildId : serverId);
if(guild)
// guild.commands here will have the existing object. 
// Modify it as required and then use findOneAndUpdate again

【讨论】:

这个解决方案的问题是它将完全覆盖具有 x 值的命令,而不是更改特定属性。 Commands 里面有嵌套对象,只是不在 Schema 中 我实际上已经找到了我的问题的答案。【参考方案2】:

解决方案非常简单。我从这个网站上拿的:https://mongoosejs.com/docs/2.7.x/docs/schematypes.html

表扬:

由于它是无模式类型,您可以将值更改为您喜欢的任何其他值,但 Mongoose 失去了自动检测/保存的能力 这些变化。 “告诉” Mongoose Mixed 类型的值具有 改变了,调用文档传递的.markModified(path)方法 您刚刚更改的 Mixed 类型的路径。

所以,每当我更新命令时(也就是每当我更改访问、有界或禁用变量时),我都会在命令函数上使用标记修改方法。我的代码是:

guildSchema.virtual("saveCommands").set(function(name)
  if(["access", "bounded", "disabled"].includes(name)) this.markModified('commands');
);

【讨论】:

以上是关于Mongoose:无法将数据保存到空对象的主要内容,如果未能解决你的问题,请参考以下文章

Mongoose 将默认设置为空对象

Mongoose .save() 返回空错误对象,不保存在数据库中

将对象粘贴到空单元格/工作表时出现错误 424 未被识别为对象

将颤振代码迁移到空安全后,模拟对象不接受“任何”

如何将对象添加到空的用户界面文件?

如何在for循环中将数据附加到空列表?