ES6扩展运算符 - Mongoose结果复制

51

我正在使用mongo DB和mongoose开发一个express js API。

我想要创建一个由几个变量和mongoose请求结果组成的Javascript es6对象,并希望使用es6 spread操作符进行操作:

MyModel.findOne({_id: id}, (error, result) => {
   if (!error) {
      const newObject = {...result, toto: "toto"};
   }
});

问题是将扩展运算符应用于result会以奇怪的方式转换它:

newObject: {
   $__: {
      $options: true,
      activePaths: {...},
      emitter: {...},
      getters: {...},
      ...
      _id: "edh5684dezd..."
   }
   $init: true,
   isNew: false,
   toto: "toto",
   _doc: {
      _id: "edh5684dezd...",
      oneFieldOfMyModel: "tata",
      anotherFieldOfMyModel: 42,
      ...
   }
}

我有点理解mongoose会丰富对象结果,以便允许特定的交互,但在执行此操作之前,如果我console.log它,它仅显示一个简单的对象而没有所有这些内容。

我不想通过 ...result._doc 这样做以避免作弊,因为我抽象出了这个部分,它不适合使用这种方式。也许有一种方法可以复制不带增强内容的对象。

谢谢您的时间。


1
看一下它的 toString 方法。这就是你在控制台中看到的内容。 - Jonas Wilms
1
对结果执行 toString 方法会返回只包含我的字段的简单对象,因此看起来对象是正常的,但当我尝试使用扩展运算符时,它会改变对象结构。使用 Object.assign() 也会产生完全相同的结果。 - Lucien Perouze
好的,那么执行 console.log( result.toString ) 来查看它是如何工作的... - Jonas Wilms
3个回答

118
你可以使用Mongoose的 Document.toObject() 方法,它将返回从数据库中提取的基础纯JavaScript对象。
const newObject = {...result.toObject(), toto: "toto"};
您可以在此处了解更多有关 .toObject() 方法的信息

1
好的,就这么简单,这正是我一直在寻找但未能找到的 :) 谢谢,希望它能帮助更多的人。 - Lucien Perouze
谢谢您,我有一个后续问题,做完这个之后我不能再使用newObject.toJSON(),而之前我可以使用result.toJSON()。这里有什么替代方法吗? - AbsoluteSith
3
您可以直接在数据库查询中使用.lean,更多信息请参阅此处 - Abdullah Oladipo

2

我遇到了同样的问题,并找到了一些除了之前答案以外的替代方案。

选项1 Object.assign():

Object.assign()方法将一个或多个源对象的所有可枚举自有属性复制到目标对象中。它返回修改后的目标对象。

示例:

Object.assign(result, {toto: "toto");

选项2 Document.prototype.set():

设置一个或多个路径的值。

doc.set("toto", "toto")



0

对某些人而言,这可能会有所帮助:

const newObject = {
    ...JSON.parse(JSON.stringify(result)),
    toto: "toto"
};

但如果您在模式中使用了日期、函数、未定义值、正则表达式或无限大,则会受到限制。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接