为什么 Virtual Populate 不能在 Node js 和 mongoose 上运行?场景:用户的产品和评论

why Virtual Populate not working on Node js and mongoose? Scenario : Product and Review by user

我有评论和产品 model.If 用户对特定产品 (id) 进行评论,然后将其存储在评论模型数据库中,但我不喜欢将用户评论存储在产品模型数据库中。所以,我使用了虚拟使用虚拟属性填充产品模型而不是子 referencing.After,如果我们使用产品 ID 查看详细信息,我们可以看到 json 格式的用户评论但未保存在 database.But 问题是我的虚拟属性(在产品模型中)无法正常工作,因为当我在已经有用户评论(存储在评论模型数据库中)的产品 ID 中发送请求时,它没有以 json 格式显示用户评论。什么是这里有问题吗?

用户对数据库中存储的产品 (id) 的评论

发送该产品 ID 的请求以使用虚拟属性以 json 格式查看用户评论(但在 json 中未找到评论)

在产品型号中

const productSchema = new Schema({

    name: {
        type: String,
        required: true,
        trim: true,
    },

    slug: {
        type: String,
        required: true,
        unique: true,
    },
    price: {
        type: String,
        required: true,
    },
    quantity: {
        type: Number,
        required: true,
    },
    description: {
        type: String,
        required: true,
        trim: true,
    },
    offer: {
        type: Number,
    },
    discount: {
        type: Number,
    },
    productPictures: [{
        img: {
            type: String,
        },
    }, ],

   
    mainCategory: {
        type: mongoose.Schema.Types.ObjectId,
        ref: "category",
        required: [true, "It is a required field"],
    },
    sub1Category: {
        type: mongoose.Schema.Types.ObjectId,
        ref: "category",
        required: [true, "It is a required field"],
    },
    sub2Category: {
        type: mongoose.Schema.Types.ObjectId,
        ref: "category",
        required: [true, "It is a required field"],
    },
    createdBy: {
        type: mongoose.Schema.Types.ObjectId,
        ref: "admin",
        required: true,
    },
    vendor: {
        type: mongoose.Schema.Types.ObjectId,
        ref: "vendor",
    },
    createdAt: {
        type: String,
        default: moment().format("DD/MM/YYYY") + ";" + moment().format("hh:mm:ss"),
    },
    updatedAt: {
        type: String,
        default: moment().format("DD/MM/YYYY") + ";" + moment().format("hh:mm:ss"),
    },
},

{
    toJson: { virtuals: true },
    toObject: { virtuals: true },
}
);

    productSchema.virtual("reviews", {

ref: "review",

foreignField: "product",

localField: "_id",

// justOne: true
}); 

const Product = mongoose.model("product", productSchema);                   
           module.exports = Product;

正在审查模型

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



const reviewSchema = new Schema({

user: {
    type: mongoose.Schema.Types.ObjectId,
    ref: "user",
    required: [true, "Review must belong to user"],
},
product: {
    type: mongoose.Schema.Types.ObjectId,
    ref: "product",
    required: [true, "Review must belong to the product"],
},
review: {
    type: String,
    required: [true, "Review cannot be empty"],
},
rating: {
    type: Number,
    min: 1,
    max: 5,
},
createdAt: {
    type: String,
    default: moment().format("DD/MM/YYYY") + ";" + moment().format("hh:mm:ss"),
},
updateddAt: {
    type: String,
    default: moment().format("DD/MM/YYYY") + ";" + moment().format("hh:mm:ss"),
},
}, {
toJson: { virtuals: true },
toObject: { virtuals: true },
});


// pre middleware and populating user and product(we can also do populate in getAllReview in controller)

reviewSchema.pre(/^find/, function(next) {
// ^find here is we use regex and can able to find,findOne ...etc
this.populate({
    path: "product",
    select: " _id name",
}).populate({
    path: "user",
    select: " _id fullName",
});
next()
});


const Review = mongoose.model("review", reviewSchema);

module.exports = Review;

在Review.js

const Review = require("../../models/Review.Models")
exports.createReview = async(req, res) => {
const review = await Review.create(req.body)

return res.status(201).json({
    status: true,
    review
})
}


exports.getAllReviews = async(req, res) => {
try {
    const reviews = await Review.find()

    return res.status(200).json({
        status: true,
        totalReviews: reviews.length,
        reviews
    })
} catch (error) {
    return res.status(400).json({
        status: false,
        error
    })
}}

在Product.js

const Product = require("../../models/Product.Models");
exports.getProductDetailsById = async(req, res) => {
try {
    const { productId } = req.params;

    // const { productId } = req.body;

    if (productId) {
        const products = await Product.findOne({ _id: productId })
            .populate('reviews')

        return res.status(200).json({
            status: true,
            products,
        });
    } else {
        console.log("error display");
        return res.status(400).json({
            status: false,
            error: "params required...",
        });
    }
} catch (error) {
    return res.status(400).json({
        status: false,

        error: error,
    });
}

在 Product.js

试试这个
 try {
if (productId) {
  const products = await Product.findOne({ _id: productId }).populate(
    "reviews"
  );


  console.log(products);
  if (products) {
    return res.status(200).json({
      status: true,
      message: "Products is listed",
      products,
      reviw: products.reviews,
    });

只需要添加响应发送

 return res.status(200).json({
      status: true,
      message: "Products is listed",
      products,
      reviw: products.reviews,
    });