mongoose schema中的transform是如何工作的?

1wnzp6jl  于 2023-04-30  发布在  Go
关注(0)|答案(2)|浏览(156)

我的用户模型图片:

在我的用户模型中,我有这个作为我的用户模型的第二个参数,删除__v并将_id替换为id

{
    toJSON: {
      transform: function (doc, ret) {
        ret.id = ret._id;
        delete ret._id;
        delete ret.password;
        delete ret.__v;
      },
    },
  }

在我的登录路由器中,我有这样的东西:

const existingUser = await User.findOne({email});
console.log("existingUser*", existingUser)
res.status(200).send(existingUser);

我从我的控制台得到这个。原木

{
  _id: 5fe81e29fdd22a00546b05e3,
  email: 'chs@hotmail.fr',
  password: '0636b425ef0add0056ec85a5596eacf9ff0c71f8c2a1d4bad068a8679398e11870df12262722b911502eacb5fca23cef0cdd3b740481102ead50c58756d14a34.3f82d856ad93bc99',
  __v: 0
}

但在 Postman 我收到了这个:

{
    "email": "chs@hotmail.fr",
    "id": "5fe81e29fdd22a00546b05e3"
}

我知道使用transform,“如果设置了,mongoose将调用此函数来允许您转换返回的对象”。
但是,有人能向我解释一下什么时候发生的'转换',以证明控制台之间的区别。日志和我在postman中收到的数据?
这和异步有关系吗?

gblwokeq

gblwokeq1#

res.status(200).send(existingUser);看起来像expressjs(或类似)控制器代码,所以我假设它是Express。
.send(body)方法将响应作为字符串发送到客户端浏览器(从技术上讲)。因此,在实际传输之前,如果body参数还不是字符串,则将其转换为string。代码中的existingUser不是字符串,而是mongoose对象,因此express将其转换为字符串,实际上这将类似于以下代码:

res.status(200)
  .send(
    existingUser.toString() // .toString() here is the key
  );

在此基础上,mongoose对象的.toString()被代理到.toJSON()方法,因此代码等价于以下内容:

...
  .send(
    existingUser.toJSON() // .toJSON() here
  );

...而.toJSON()方法考虑了您为mongoose模式指定的transform(doc, ret)选项。
另一方面,console.log()不使用参数的底层.toString()/.toJSON()方法。如果您想打印以控制结果,则最终消费者将收到结果(Postman,F。e.),那么你应该手动调用转换:

console.log(existingUser.toJSON()); // like this, transformed, but not stringified
console.log(existingUser.toString()); // or like this, but already stringified
console.log(JSON.stringify(existingUser, null, 3)); // or transform and then stringify with custom formatting (3-space tabulated instead of default single-line formatting)

整个转换链看起来像这样:

Model
  -> `.toJSON()` 
    -> Mongoose transforms model internally into POJO
      if custom transform is defined
      -> Mongoose passes POJO to user defined `transform(doc, ret)`, 
         where `doc` - original document, `ret` - internally transformed POJO
        -> `ret` is returned
      else
      -> POJO is returned
bbuxkriu

bbuxkriu2#

在Mongoose中,模式中的transform选项允许您在从数据库返回到应用程序之前修改从数据库返回的对象。transform函数将原始MongoDB文档作为参数,并应返回将返回给应用程序的转换后的对象。

const mongoose = require("mongoose");
const Schema = mongoose.Schema;

const mySchema = new Schema({
   field1: String,
   field2: Number
}, {
   toObject: {
      transform: function (doc, ret) {
         ret.id = ret._id;
         delete ret._id;
         delete ret.__v;
      }
   }
});

const Model = mongoose.model("Model", mySchema);

https://www.cltechhome.com/2023/02/how-transform-in-mongoose-schema-works.html

相关问题