【问题标题】:toJSON method is ignored when populating sub documents填充子文档时忽略 toJSON 方法
【发布时间】:2022-01-07 03:41:18
【问题描述】:

我需要从 JSON 响应中删除某些字段。我使用了toJSON() 方法来执行此操作。这是我的模态方法的代码。

    User.methods.toJSON = function () {
      let obj = this.toObject()
    
      delete obj.resetPasswordToken
      delete obj.resetPasswordExpire
      delete obj.otp
      delete obj.otpExpire
      return obj
    }

上面的代码工作正常,但是当我用我的媒体模型填充用户模式时,它不会删除我从 JSON 响应中删除的字段。

    const allMedia = await Media.find({}).populate({
      path: 'uploadedBy', // this is the user document 
    })

这是我为使用媒体模型填充用户模型而编写的代码。但问题是用户填充了媒体,但它不会忽略我从 toJSON() 方法中删除的字段。

    {
        "name": null,
        "sizes": [],
        "isPrivate": false,
        "_id": "61d6d1a1fcaf7337f6f186de",
        "path": "http://192.168.1.7:2121/uploads/2022/1/7b37e2bc-b313-4b08-abd6-101e99c36527.png",
        "uploadedBy": {
            "firstName": "abc",
            "lastName": "abc",
            "role": "ADMIN",
            "resetPasswordToken": "77bda3f7794d305d7771fc23d932e1e9922df02c71b02c3564ad46b22ceac27e",
            "resetPasswordExpire": "1640954443294",
            "otp": null,
            "otpExpire": null,
            "_id": "61ceea9ce989f2d986fa9c5c",
            "userName": "abc",
            "email": "abc@gmail.com",
            "createdAt": "2021-12-31T11:33:48.066Z",
            "updatedAt": "2021-12-31T13:08:36.245Z"
        },
        "createdAt": "2022-01-06T11:25:21.839Z",
        "updatedAt": "2022-01-06T11:25:21.839Z"
    }

如果有人可以提供帮助,将不胜感激。

提前致谢,

【问题讨论】:

  • 显然您没有将具有已删除属性的函数的结果分配给新变量,因此您最终得到了未修改的对象...
  • 我同意,@R2D2。但我不知道有什么方法可以返回修改后的对象。
  • 虽然,我可以在返回对象之前创建一个中间件或辅助函数。但如果有的话,我正在寻找更好的方法。 @R2D2

标签: javascript node.js mongodb mongoose mongoose-populate


【解决方案1】:

您可以为 Media 架构的每个查询定义 pre 挂钩。

const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const schema = new Schema(...);

schema.pre('find', function () {
  this.populate('uploadedBy');
  this.select('-resetPasswordToken -resetPasswordExpire -otp -otpExpire');
});

您可以为其他查询添加新的pre 挂钩,就像find 一样。

您可以找到更多详细信息here

【讨论】:

  • 我不想对所有查询重复它,所以我正在寻找可以为所有查询全局排除它的中间件或实用程序函数。
  • 我更新了我的答案。你能再试一次吗?
  • 谢谢,伙计!这正是我所需要的。但是,我可能还需要使用其他钩子。例如findOne、findOneAndUpdate、update 等。只是为了确保我不会公开这些字段。
  • 欢迎。是的,我补充说你可以对其他方法做同样的事情。
  • 好的,谢谢大家!
【解决方案2】:

这里是一个使用聚合的例子

const allMedia = await Media.aggragate([
  $lookup: {
    from: 'uploadedBy',
    localField: 'uploadedBy',
    foreignField: '_id',
    // your variable
    as: 'uploadedBy',
  },
  {
    $project: {
//removing the field you want to remove by attibuting a Zero
      resetPasswordToken:0,
      resetPasswordExpire: 0,
      otp:0,
      otpExpire:0
      // select the field you want to display 
      fieldYouWantoToDisplay: 1,
    },
  },
])

【讨论】:

  • 这将删除字段,但我不想为所有查询删除它,这就是我从 toJSON 方法全局删除它的原因。如果我使用“聚合”或“填充”来重复所有查询,我必须重复它。
猜你喜欢
  • 1970-01-01
  • 2020-05-15
  • 2011-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-16
  • 2017-01-27
  • 1970-01-01
相关资源
最近更新 更多