当前位置: 首页 > 知识库问答 >
问题:

Laravel口才在枢轴关系中执行聚合功能

陶星辰
2023-03-14

我想执行每个产品的平均评级,存储在数据透视表中称为“评论”。下面是我现有的代码。

产品型号:

public function reviews(){
        return $this->belongsToMany(User::class,'reviews')->withPivot('comment','rating')->withTimestamps();
    }
public function getProductRatingAttribute(){
        return $this->reviews()->average('rating');
    }

用户模型:

public function reviews(){
        return $this->belongsToMany(Product::class,'reviews')->withPivot('comment','rating')->withTimestamps();
    }

审查的迁移

Schema::create('reviews', function (Blueprint $table) {
            $table->id();
            $table->timestamps();
            $table->unsignedBigInteger('user_id');
            $table->unsignedBigInteger('product_id');
            $table->string('comment')->nullable();
            $table->integer('rating');
            $table->foreign('user_id')->references('id')->on('users');
            $table->foreign('product_id')->references('id')->on('products');
        });

我试图使用下面的代码构造预期的输出,但它导致了N+1个问题,因为它没有利用Laravel口才的急切加载。

$s = Product::with('reviews')->append('product_rating');

预期产出:

{
  "msg": [
    {
      "id": 4,
      "created_at": "2021-04-09T07:32:35.000000Z",
      "updated_at": "2021-04-09T07:32:35.000000Z",
      "name": "MacDonald",
      "nickname": "MCD",
      "users_id": 1,
      "price": "0.00",
      "product_rating": "3.3333",
      "reviews": [
        {
          "id": 1,
          "name": "John Smith",
          "email": "john.smith@hotmail.com",
          "email_verified_at": null,
          "created_at": "2021-04-08T13:29:13.000000Z",
          "updated_at": "2021-04-08T13:29:13.000000Z",
          "role": 0,
          "pivot": {
            "product_id": 4,
            "user_id": 1,
            "comment": "Ouch",
            "rating": 3,
            "created_at": "2021-05-01T11:51:26.000000Z",
            "updated_at": "2021-05-01T11:52:07.000000Z"
          }
        },
        {
          "id": 2,
          "name": "Kelvin Ooi",
          "email": "kelvin.ooi@hotmail.com",
          "email_verified_at": null,
          "created_at": "2021-04-08T13:29:13.000000Z",
          "updated_at": "2021-04-13T12:07:11.000000Z",
          "role": 1,
          "pivot": {
            "product_id": 4,
            "user_id": 2,
            "comment": "Ouch",
            "rating": 5,
            "created_at": "2021-05-01T11:51:26.000000Z",
            "updated_at": "2021-05-01T11:52:07.000000Z"
          }
        },
        {
          "id": 1,
          "name": "John Smith",
          "email": "john.smith@hotmail.com",
          "email_verified_at": null,
          "created_at": "2021-04-08T13:29:13.000000Z",
          "updated_at": "2021-04-08T13:29:13.000000Z",
          "role": 0,
          "pivot": {
            "product_id": 4,
            "user_id": 1,
            "comment": "Ouch",
            "rating": 2,
            "created_at": "2021-05-01T11:51:26.000000Z",
            "updated_at": "2021-05-01T11:52:07.000000Z"
          }
        }
      ]
    },
    {
      "id": 10,
      "created_at": null,
      "updated_at": null,
      "name": "Mary Bown",
      "nickname": "MB",
      "users_id": 1,
      "price": "2.88",
      "product_rating": "2.0000",
      "reviews": [
        {
          "id": 1,
          "name": "John Smith",
          "email": "john.smith@hotmail.com",
          "email_verified_at": null,
          "created_at": "2021-04-08T13:29:13.000000Z",
          "updated_at": "2021-04-08T13:29:13.000000Z",
          "role": 0,
          "pivot": {
            "product_id": 10,
            "user_id": 1,
            "comment": "Ouch",
            "rating": 2,
            "created_at": "2021-05-01T11:51:26.000000Z",
            "updated_at": "2021-05-01T11:52:07.000000Z"
          }
        }
      ]
    },
    {
      "id": 11,
      "created_at": null,
      "updated_at": null,
      "name": "Pizza Hut",
      "nickname": "pizzahut",
      "users_id": 1,
      "price": "4.10",
      "product_rating": null,
      "reviews": [
        
      ]
    },
    {
      "id": 12,
      "created_at": "2021-04-09T08:00:42.000000Z",
      "updated_at": "2021-04-09T08:00:42.000000Z",
      "name": "Domino Pizza",
      "nickname": "domino",
      "users_id": 3,
      "price": "0.00",
      "product_rating": null,
      "reviews": [
        
      ]
    },
    {
      "id": 13,
      "created_at": "2021-04-26T16:12:53.000000Z",
      "updated_at": "2021-04-26T16:12:53.000000Z",
      "name": "Chicken Chop",
      "nickname": "chickchop",
      "users_id": 3,
      "price": "0.00",
      "product_rating": null,
      "reviews": [
        
      ]
    }
  ]
}

共有1个答案

酆意智
2023-03-14

追加是对每个记录执行查询。

为什么不对集合本身执行平均?

$s = Product::with('reviews')->get();
$avg = $s->avg('pivot.rating');

或者,您可以修改relationship方法,以包含平均评等的原始选择。

 类似资料:
  • 我在连接Laravel中的数据库模型时遇到问题。 现在,我想把它们连接起来,就像,每个用户可以有多个公司,每个公司都有自己的company_details。 我的用户。php模型如下所示: 如何从company_details表中获取值?

  • 我有一个数据库结构,其中我有一个用户和公司之间的多对多关系表。为此,我有一个交叉引用表company_user。此外,每个用户在公司中都有一定的角色,因此交叉引用表也有role_id。问题是,由于某种原因,当我试图从交叉引用表中检索角色时,我会出现异常。 以下是我如何定义公司模型中的关系: 现在,如果我只是尝试从pivot获取角色id,一切都会正常工作: 但是我还需要角色的数据,所以我在自定义透视

  • 问题内容: 如何执行枢纽功能 我有一张有数据的表 但我需要的格式为 这样。 如何执行数据透视功能以这种格式获取。 请帮帮我........ 我用过我的查询 结果显示为 但在这里我也有3个星期一的记录,而不是一个星期一的记录… 如何获得每天1天的一个记录…? 问题答案: 试试这个: PIVOT运算符未“消耗”的任何列将保留在最终结果集中,从而增加了基数。

  • 在Laravel中,有可能把关系放在关系中吗? 我的两个模型: 商店 供应商 我的商店和供应商关系模型: null 正如您所看到的,我有许多商店和供应商,每个都可以通过SupplierStore表相互关联。 这很好用。 我的问题是,对于每一个关系(商店和供应商),可能有许多交货日。 我想如果我进入SupplierStore模型并添加: 会工作,但我似乎没有办法通过雄辩来访问这些数据? 我希望做这样

  • 我有一个帖子模型、一个用户模型和一个评论模型。 我的用户可以发布帖子,也可以评论帖子。 我想得到帖子的评论,但是,我的用户也可以阻止用户。 我的意思是,如果活动用户有一些其他被阻止的用户,并且如果post的评论有这些用户创建的评论,我必须排除他们。 问题来了。 我想使用帖子和评论的关系,因为这里的工作还没有完成。但是如果我在posts数组中使用foreach,那么继续使用foreach将非常奇怪;

  • 我有users表,它与vendordetails表有hasOne关系。 vendordetails表包含country_id、state_id和city_id,与Country、State和City模型有归属关系。 vendorDetail.php模型为:- 如果我查询users表,如何获取国家、州和城市的记录。 在这个查询中,它只找到vendordetails表的结果,我还想要country、s