【问题标题】:Calculate the average value of 5 star rating by grouping a unique id通过对唯一的 id 进行分组来计算 5 星评分的平均值
【发布时间】:2020-09-05 14:14:20
【问题描述】:

我正在尝试计算当用户点击任意数量的星星时我传递给数据库的平均 5 星评级。

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

const ratingSchema = mongoose.Schema({
    userId: {
        type: Schema.Types.ObjectId,
        ref: 'User'
    },
    productId: {
        type: Schema.Types.ObjectId,
        ref: 'Product'
    },
    noOfStars: {
        type: Number,
        default: 0
    }

},{timestamp: true})

const Rating = mongoose.model('Rating', ratingSchema);

module.exports = {Rating}

这是我创建的用于发送特定产品评级的模型。当用户点击星号时,星号、producID 和 userID 将被插入到数据库中。

import React,{useEffect,useState} from 'react';

const aggregate = require("../models/rating").Rating.aggregate;
const{Rating}=require('../models/rating');

exports.RatingAdd=(req,res) =>{
    aggregate(
        [
            {
                $group:
                    {
                        _id: "$productId"


                    }
            }
        ]
    )
}

这是我创建的控制器,用于检索特定产品的平均星级并将其显示在前端。我不明白如何获取相同产品 ID 的计数,然后将星值总数除以产品 ID 计数。我无法获得每个产品的正确平均值。我应该如何编辑我的代码以显示每个产品的平均星值并将平均星值和产品 ID 传递给我的前端?

【问题讨论】:

    标签: node.js mongodb express mongoose mongodb-query


    【解决方案1】:
    db.products.aggregate({$group:{_id:'$productId',count:{$sum:1},avg:{$avg:'$noOfStars'}}},{$project:{_id:1,count:1,avg:{$round:['$avg',1]}}})
    

    这是你需要的吗?

    {
        "_id" : ObjectId("5ec40ff1ce367b3630df8f13"),
        "userId" : "A",
        "productId" : "C",
        "rating" : 1
    }
    {
        "_id" : ObjectId("5ec40ff3ce367b3630df8f14"),
        "userId" : "A",
        "productId" : "C",
        "rating" : 2
    }
    {
        "_id" : ObjectId("5ec40ff5ce367b3630df8f15"),
        "userId" : "A",
        "productId" : "C",
        "rating" : 3
    }
    {
        "_id" : ObjectId("5ec40ff6ce367b3630df8f16"),
        "userId" : "A",
        "productId" : "C",
        "rating" : 4
    }
    {
        "_id" : ObjectId("5ec40ffdce367b3630df8f17"),
        "userId" : "A",
        "productId" : "A",
        "rating" : 4
    }
    {
        "_id" : ObjectId("5ec40ffece367b3630df8f18"),
        "userId" : "A",
        "productId" : "A",
        "rating" : 5
    }
    {
        "_id" : ObjectId("5ec41001ce367b3630df8f19"),
        "userId" : "A",
        "productId" : "A",
        "rating" : 4.5
    }
    {
        "_id" : ObjectId("5ec41003ce367b3630df8f1a"),
        "userId" : "A",
        "productId" : "A",
        "rating" : 4.2
    }
    {
        "_id" : ObjectId("5ec41009ce367b3630df8f1b"),
        "userId" : "A",
        "productId" : "B",
        "rating" : 3.2
    }
    {
        "_id" : ObjectId("5ec4100bce367b3630df8f1c"),
        "userId" : "A",
        "productId" : "B",
        "rating" : 2.2
    }
    {
        "_id" : ObjectId("5ec4100ece367b3630df8f1d"),
        "userId" : "A",
        "productId" : "B",
        "rating" : 1.2
    }
    

    结果:

    { "_id" : "C", "count" : 4, "avg" : 2.5 }
    { "_id" : "A", "count" : 4, "avg" : 4.4 }
    { "_id" : "B", "count" : 3, "avg" : 2.2 }
    

    编辑测试数据并包含 $round。

    【讨论】:

    • 是的,这就是我要找的,谢谢,我的下一个问题是如何将平均值转换为小于 5 的值,因为我的前端只有 5 颗星,我将无法展示平均值
    • 如果你在 mongoDB 中的 noOfStars 都小于 5。调用 $avg 肯定会小于 5。
    • 我编辑了我使用的测试数据...如果您需要,我已经包含了一个四舍五入到最接近的小数点后 1 位。如果您担心您的 noOfStars 中是否有超过 5 个,只需在 $group 之前进行 $match,尽管这违背了评级系统的目的,因为您应该在插入数据库之前对其进行验证。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-03
    • 2015-08-27
    • 1970-01-01
    • 2020-12-12
    • 2017-08-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多