简体   繁体   English

Mongoose:无法将数据保存到空 Object

[英]Mongoose: Unable To Save Data To Empty Object

Here is my situation:这是我的情况:

I have a simple Schema that has an object called commands which I originally set to {} .我有一个简单的架构,它有一个 object 调用命令,我最初设置为{}

commands:{}

When I went to add a document to the database, I looped through a file of commands and added them to the object by doing command["command"] = "blah blah";当我将文档添加到数据库时,我遍历了一个命令文件,并通过执行command["command"] = "blah blah"; . . The way I did that is as follows (The code I work is quite old):我这样做的方式如下(我工作的代码很旧):

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();
});

The commands contain the following (I'll use two commands for my example):命令包含以下内容(我将在示例中使用两个命令):

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
   }
 }

Fastforwarding to now, I made a config file that is supposed to edit these commands.快进到现在,我制作了一个应该编辑这些命令的配置文件。 The code I wrote works perfectly fine;我写的代码工作得很好; however, Mongoose is unable to save any of the command's changes.但是,ZCCADCDEDB567ABAE643E15DCF0974E503Z 无法保存命令的任何更改。 Everything else in my Schema works in the config file except anything related to commands.除了与命令相关的任何内容外,我的 Schema 中的所有其他内容都可以在配置文件中使用。

I know what the problem.我知道什么问题。 Mongoose can't find the command in the Schema and gets confused somehow. ZCCADDEDB567ABAE643E15DCF0974E503Z 在 Schema 中找不到命令,不知何故感到困惑。 And I know I could fix it by adding all of the commands and their properties to the Schema.而且我知道我可以通过将所有命令及其属性添加到 Schema 来修复它。 The only problem with that is it's tedious and is not a clean solution to me adding any new commands.唯一的问题是它很乏味,并且不是我添加任何新命令的干净解决方案。 Plus, I have all of the information for the commands in a separate file, so I don't want to rewrite what I already wrote.另外,我将命令的所有信息放在一个单独的文件中,所以我不想重写我已经写的内容。

My question is: is there a workaround to my problem?我的问题是:我的问题有解决方法吗? I tried setting commands to Schema.Types.Mixed , but that didn't fix it.我尝试将commands to Schema.Types.Mixed ,但这并没有解决它。 I also searched all around for something similar but could not find anything.我也到处寻找类似的东西,但找不到任何东西。

Here is the full Schema as requested:这是所要求的完整架构:

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);

Use findOneAndUpdate to update the existing document in the collection.使用findOneAndUpdate更新集合中的现有文档。

let the object that you want to update in "commands" in mongodb be in x variable.让您要在 mongodb 的“命令”中更新的 object 位于x变量中。

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

The object which you have stored in x variable will directly be updated/replaced with this new data when a match is found.当找到匹配项时,您存储在x变量中的 object 将直接更新/替换为该新数据。

UPDATE TO NOT COMPLETELY REPLACE EXISTING OBJECT更新不完全替换现有的 OBJECT

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
}

The solution is quite simple.解决方案非常简单。 I took it from this site: https://mongoosejs.com/docs/2.7.x/docs/schematypes.html我从这个网站上拿了它: https://mongoosejs.com/docs/2.7.x/docs/schematypes.html

To give credit:给予信任:

Since it is a schema-less type, you can change the value to anything else you like, but Mongoose loses the ability to auto detect/save those changes.由于它是无模式类型,您可以将值更改为您喜欢的任何其他值,但 ZCCADCDEDB567ABAE643E15DCF0974E503Z 失去了自动检测/保存这些更改的能力。 To "tell" Mongoose that the value of a Mixed type has changed, call the.markModified(path) method of the document passing the path to the Mixed type you just changed.要“告诉” Mongoose Mixed 类型的值已更改,请调用文档的 .markModified(path) 方法,将路径传递给刚刚更改的 Mixed 类型。

So, whenever I update the commands (aka whenever I change the access, bounded, or disabled variables), I would use the mark modified method on the command function.因此,每当我更新命令时(也就是每当我更改访问、有界或禁用变量时),我都会在命令 function 上使用标记修改方法。 My code is:我的代码是:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM