【问题标题】:How to order by an average rating如何按平均评分订购
【发布时间】:2017-06-20 19:21:20
【问题描述】:

我正在尝试根据产品评论中给出的平均评分来订购我的产品。

这是我的表格: 产品:id、产品名称、价格、已批准 评论:id、评论、评级、product_id_fk

如何更改此设置以将最高平均评分恢复到最低?

$products = Product::where('approved', '=', 1)->orderBy('productname');
return view('pages.search')->with('products', $products)

【问题讨论】:

    标签: laravel laravel-5 eloquent laravel-5.4


    【解决方案1】:

    创建一个名为 product_review_ratings 的新表,其中包含

    product_id
    avg_rating
    

    创建一个循环遍历所有产品和求和平均评分的预定命令。保存到 product_review_ratings 表。

    在 ProductReviewRating 模型中添加与 Product 的关系

    class ProductReviewRating extends Model
    {
        public function product() {
            return $this->belongsTo(Product::class);
        }
    }
    

    现在您可以按评分排序。`

    $collection = ProductReviewRating::orderBy('avg_rating', 'desc')->get();
    

    在视野中

    @foreach ($collection as $rating)
    
        {$rating->product->name} - {$rating->avg_rating} <br>
    
    @endforeach
    

    预定命令示例(假设您在产品模型中有评论关系)

    foreach (Product::all() as $product) {
    
        ProductReviewRating::updateOrCreate(['product_id' => $product->id],[
            'product_id' => $product->id, 
            'avg_rating' => $product->reviews->pluck('rating')->avg()
        ]);
    
    }
    

    【讨论】:

    • 知道循环通过的“调度命令”是什么吗?
    • @detinu20 你知道怎么做命令吗?解决方案来了!
    • 我应该将计划命令放置在模型中还是控制器中?抱歉,我的 php laravel 知识很少
    【解决方案2】:

    简单的方法(不需要预定命令)是计算评论的 avg() 并将结果与​​产品连接:

    $products = DB::table('reviews')
                ->join('products', 'reviews.product_id', '=', 'products.id')
                ->select(DB::raw('avg(rating) as average, products.*'))
                ->groupBy('product_id')
                ->orderBy('average', 'desc')
                ->get();
    

    将其作为产品模型中的一种方法,或者更好的是产品存储库。

    【讨论】:

    • 那里的平均收视率在哪里?
    • 快点!我的错。它是 avg(评级)而不是 avg(*)。答案已编辑。
    • SQLSTATE[42000]:语法错误或访问冲突:1055 SELECT 列表的表达式 #2 不在 GROUP BY 子句中,并且包含在功能上不依赖于列的非聚合列“products.products.id”在 GROUP BY 子句中;这与 sql_mode=only_full_group_by (SQL: select avg(ratings) as average, products.* from reviews inner join products on reviews.product_id = reviews.id group by @987654328 不兼容@ order by average desc) - 是我在该代码上遇到的错误。有什么想法吗?
    【解决方案3】:

    现在接受的答案已经过时了。
    有一个 builtin withAvg eloquent 函数可以完成所需的工作。

    这些方法会将{relation}_{function}_{column} 属性放在生成的模型上

    所以要从评论表中获得平均评分:

    Product::where('approved', '=', 1)->withAvg('reviews', 'rating')->orderBy('reviews_avg_rating');
    

    现在您可以像使用产品评级一样简单:$product-&gt;reviews_avg_rating
    生成的 sql 将使用子查询在每个产品上获取它:

    select `products`.*, (select avg(`reviews`.`rating`) from `reviews` where `products`.`id` = `reviews`.`product_id`) as `reviews_avg_rating` from `products`
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-04-24
      • 2018-01-04
      • 2011-10-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-27
      相关资源
      最近更新 更多