mongoose 虚拟属性在 findById 属性中不起作用

Posted

技术标签:

【中文标题】mongoose 虚拟属性在 findById 属性中不起作用【英文标题】:mongoose virtual property not working in findById property 【发布时间】:2021-04-29 19:39:09 【问题描述】:

我有一个serviceSchema,如下所示:

const serviceSchema = new mongoose.Schema(
  
    user: 
      type: mongoose.Schema.Types.ObjectId,
      ref: "User",
      required: true,
    ,
    title: 
      type: String,
      required: true,
    ,
    description: 
      type: String,
      required: true,
    ,
    tags: [
      
        type: String,
        required: true,
      ,
    ],
    image: 
      type: String,
      required: true,
      get: (rawImage) => 
        return `$config.base_url/uploads/$rawImage`;
      ,
    ,
  ,
  
    timestamps: true,
    toJSON:  getters: true, virtuals: true ,
  
);

我已经定义了一个这样的虚拟:

serviceSchema.virtual("avg_satis").get(function () 
  Session.find( service: this._id, status: "conf" , "satisfaction")
    .lean()
    .then((sessions) => 
      let sum = 0;
      sessions.forEach((session) => 
        sum += session.satisfaction;
      );
      console.log(sum / sessions.length);
      return sum / sessions.length;
    )
    .catch((err) => console.log(err));
);

当我执行这样的查询时:

      const service = await Service.findById(req.params.service_id).populate(
        "user",
        "_id name pp"
      );
      console.log(service.avg_satisf);

虚拟未定义。

我也尝试像这样转换虚拟(没有承诺):

serviceSchema.virtual("avg_satis").get(function () 
  Session.find( service: this._id, status: "conf" , "satisfaction")
    .lean()
    .exec((err, sessions) => 
      if (err) 
        console.log(err);
      
      let sum = 0;
      sessions.forEach((session) => 
        sum += session.satisfaction;
      );
      console.log(sum / sessions.length);
      return sum / sessions.length;
    );
);

【问题讨论】:

virtual 不允许异步功能。 @hoangdv 我该如何解决这个问题? 将会话模式添加到问题 【参考方案1】:

虚拟字段在数据库中不存在。它是一种速记,所以你不能查询它。 你要的是打电话populate,请阅读文档并使用它。

如果你真的想在虚拟中得到一个承诺

serviceSchema.virtual("avg_satis").get(function () 
  // return promise to caller
  return Session.find( service: this._id, status: "conf" , "satisfaction")
    .lean()
    .then((sessions) => 
      let sum = 0;
      sessions.forEach((session) => 
        sum += session.satisfaction;
      );
      console.log(sum / sessions.length);
      return sum / sessions.length;
    )
    .catch((err) => console.log(err));
);


// outside
await service.avg

在文档中还有另一种方式,例如静态或方法

----更新

它已经在猫鼬文档中

  // define a schema
  const animalSchema = new Schema( name: String, type: String );

  // assign a function to the "methods" object of our animalSchema
  animalSchema.methods.findSimilarTypes = function(cb) 
    return mongoose.model('Animal').find( type: this.type , cb);
  ;

所以

  // define a schema
  serviceSchema.methods.caleAvg = async function() 
    return Session.find( service: this._id, status: "conf" , "satisfaction")
    .lean()
    .then((sessions) => 
      let sum = 0;
      sessions.forEach((session) => 
        sum += session.satisfaction;
      );
      console.log(sum / sessions.length);
      return sum / sessions.length;
    ).catch((err) => console.log(err));
  ;

// outside caller
const avg = await service.caleAvg()

如果你想这样做并附加到它在 mongooDB 中的响应中,你需要研究他们的aggregate 管道。

【讨论】:

你能详细说明一下吗 不,我的意思是用有关架构的更多详细信息更新您的问题 而你在 virtual getter 中什么也没返回,你真正想要做什么? 我确实返回了一些东西:return sum / sessions.length; 但它是在一个承诺中,return Sesstion.... in getter

以上是关于mongoose 虚拟属性在 findById 属性中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

Mongoose 中的 Model.findById() - 异步/等待 [重复]

Mongoose 渲染 findById

为啥不能修改 Mongoose 查询返回的数据(例如:findById)

MEAN - mongoose 使用 findById 获取完整对象

更新 findOne()/find()/findById() 返回的文档 - mongoose

更新 findOne()/find()/findById() 返回的文档 - mongoose