猫鼬虚拟财产在 findById 财产中不起作用

时间:2021-01-26 00:21:30

标签: javascript node.js mongoose

我有一个 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;
    });
});

1 个答案:

答案 0 :(得分:-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 管道。

相关问题