【问题标题】:How can i access field from another model in mongoose model我如何从猫鼬模型中的另一个模型访问字段
【发布时间】:2021-01-12 07:40:43
【问题描述】:

我在这里做了两个 MongoDB 模型

电影模型

import mongoose from 'mongoose';

const movieSchema = new mongoose.Schema({
  title: {
    type: String,
    required: [true, 'Please Enter the Movie Title'],
    trim: true,
    minlength: 5,
    maxlength: 255
  },
  genre: {
    type: mongoose.Schema.ObjectId,
    ref: 'Genre',
    required: true
  },
  year: {
    type: Number,
    min: 1800,
    max: 3000,
    required: [true, 'Please enter the year of the movie.']
  },
  directors: [
    {
      type: String,
      minlength: 5,
      maxlength: 100
    }
  ],
  writers: [
    {
      type: String,
      minlength: 5,
      maxlength: 100
    }
  ],
  cast: [
    {
      type: String,
      minlength: 5,
      maxlength: 100
    }
  ],
  numberInStock: {
    type: Number,
    required: true,
    min: 0,
    max: 255
  },
  dailyRentalRate: {
    type: Number,
    required: true,
    min: 0,
    max: 255
  }
});

export default mongoose.model('Movie', movieSchema);

租赁模型

import mongoose from 'mongoose';
import moment from 'moment';

const rentalSchema = new mongoose.Schema({
  customer: {
    type: mongoose.Schema.ObjectId,
    ref: 'Customer',
    required: true
  },
  movie: {
    type: mongoose.Schema.ObjectId,
    ref: 'Movie',
    required: true
  },
  dateOut: {
    type: Date,
    required: true,
    default: Date.now
  },
  dateReturned: {
    type: Date
  },
  rentalFee: {
    type: Number,
    min: 0
  }
});


rentalSchema.methods.return = function () {
  this.dateReturned = new Date();

  this.rentalFee =
    moment().diff(this.dateOut, 'days') * this.movie.dailyRentalRate;
};

export default mongoose.model('Rental', rentalSchema);

返回控制器

import catchAsync from '../utils/catchAsync.js';
import AppError from '../utils/appError.js';
import Rental from '../models/rentalModel.js';
import Movie from '../models/movieModel.js';

const returns = catchAsync(async (req, res, next) => {
  const rental = await Rental.findOne({
    customer: req.body.customerID,
    movie: req.body.movieID
  });
  // console.log(rental);
  if (!rental) {
    return next(new AppError('Not Found', 400));
  }

  if (rental.dateReturned) {
    return next(new AppError('Already Returned', 400));
  }

  rental.return();
  await rental.save();
  // add movie back into stock
  await Movie.updateOne(
    { _id: rental.movie._id },
    {
      $inc: { numberInStock: 1 }
    }
  );

  res.status(400).json({
    status: 'success',
    rental
  });
});

export default returns;

返回路线

import { Router } from 'express';
import { protect } from '../controllers/authController.js';
import returns from '../controllers/returnController.js';

const router = Router();

router.post('/', protect, returns);

export default router;

问题是当我想访问租赁模型中的电影字段时,它将返回电影 ID 但我希望它返回包含电影数据的对象(类似于填充但在模型逻辑内) 所以如果我尝试访问 this.movi​​e.dailyRentalRate 它返回的值不是未定义的

【问题讨论】:

  • 请添加您的控制器或路由以查看您的代码
  • 欢迎来到stackoverflow。我建议您阅读如何提出一个好问题 (stackoverflow.com/help/how-to-ask)。
  • 好的,我添加了它们
  • 你需要一个有populate()的get路由吗?
  • 不,我想获得 this.movi​​e.dailyRentalRate 的值,但我找不到在模型中制作它的方法,因为在租赁模型中,this.movi​​e 只是一个 ObjectID,所以我想找到一种在租赁模型中填充的方法,以便 this.movi​​​​e 返回一个包含电影数据的对象,并且我可以访问 dailyRentalRate

标签: javascript node.js mongodb express mongoose


【解决方案1】:

MongoDB 有 $lookup aggregation 运算符。 Mongoose 有一个名为 populate() 的替代方法,它可以让您引用其他集合中的文档。填充是自动将文档中的指定路径替换为其他集合中的文档的过程,因此您可以使用填充来解决您的问题,例如这个:

 const rental = await Rental.findOne({
    customer: req.body.customerID,
    movie: req.body.movieID
  }).populate("movie")

它对我有用,您可以在 methods.return 中访问 this.movie.dailyRentalRate

【讨论】:

  • 租用常量将在控制器上工作并返回填充数据
  • 但在租赁模型本身中,您无法访问 this.movi​​e.dailyRentalRate 因为 this.movi​​e 将返回 ObjectID
  • 没错,因为租赁模型中的电影类型是monoose.Schema.ObjectId,它对其他文档有引用,如关系数据库中的外键,以及基于外键的连接表。如果你不想使用填充,你应该在 renatal 模式中更改电影类型,并将其他键保存在电影键中,电影:{ Id:{type: mongoose.Schema.ObjectId, required: true}, dailyRentalRate: { type :数字,必填:true,最小值:0,最大值:255 } }
猜你喜欢
  • 2017-04-11
  • 1970-01-01
  • 1970-01-01
  • 2021-05-24
  • 1970-01-01
  • 2018-10-13
  • 2019-09-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多