Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Laravel雄辩:with()vs join()JSON输出_Json_Laravel_Eloquent - Fatal编程技术网

Laravel雄辩:with()vs join()JSON输出

Laravel雄辩:with()vs join()JSON输出,json,laravel,eloquent,Json,Laravel,Eloquent,我对我的Laravel项目有以下两个疑问: $questions = \App\Answer::rightJoin('questions','answers.id_question','=','questions.id_question') ->leftJoin('users','answers.id_user','=','users.id')->where([ ['questions.id_question', '=', $id_questi

我对我的Laravel项目有以下两个疑问:

$questions = \App\Answer::rightJoin('questions','answers.id_question','=','questions.id_question')
        ->leftJoin('users','answers.id_user','=','users.id')->where([
            ['questions.id_question', '=', $id_question],
            ['questions.flg_active', '=', true],
        ])->orderBy('questions.created_at', 'desc')->paginate(5);   

基本上,第一个返回尚未回答的问题,第二个只返回已经回答的问题。 我试图对两者使用相同的blade视图,但它们有不同的JSON输出结构

第一个返回一级JSON,而第二个返回3级数据

"data": [{
        "id_answer": 42,
        "created_at": "2018-11-28 17:52:18",
        "updated_at": "2019-05-24 15:09:14",
        "id_user": 2,
        "id_question": 42,
        "str_answer": "onono onooono nonono onn ",
        "str_question": "ononon ononon onononn ?",
        "url_link": null,
        "flg_active": 1,
        "id": 1,
        "name": "Paul",
        "surname": null,
        "email": "p@yahoo.com",
        "certification": "CFA ...",
        "about": "CS, ....."
    }
以及:

如何使第一个查询返回与第二个查询相同的3个级别?


为什么会发生这种情况?

第一个是更多地利用查询生成器,并将执行一个类似以下内容的查询:

SELECT * FROM answer
RIGHT JOIN questions ON answers.id_question = questions.id_question
LEFT JOIN users ON answers.id_user = users.id
WHERE questions.id_question = $id_question
AND questions.flg_active = true
ORDER BY questions.created_at desc
OFFSET 0
LIMIT 15
SELECT * FROM answer
ORDER BY created_at desc
OFFSET 0
LIMIT 15

SELECT * FROM question
WHERE answer_Id IN ($answer_ids) // Will be like (1, 5, 6, 7). All the ids retrieve from the first query

SELECT * FROM user
WHERE queston_id IN ($user_ids)
此查询将从所有表中返回数据,这些数据正是sql计算数据的方式。Laravel/Eloquent不知道如何将其可靠地转换为雄辩的格式

第二个将执行3个查询,如下所示:

SELECT * FROM answer
RIGHT JOIN questions ON answers.id_question = questions.id_question
LEFT JOIN users ON answers.id_user = users.id
WHERE questions.id_question = $id_question
AND questions.flg_active = true
ORDER BY questions.created_at desc
OFFSET 0
LIMIT 15
SELECT * FROM answer
ORDER BY created_at desc
OFFSET 0
LIMIT 15

SELECT * FROM question
WHERE answer_Id IN ($answer_ids) // Will be like (1, 5, 6, 7). All the ids retrieve from the first query

SELECT * FROM user
WHERE queston_id IN ($user_ids)
Eloquent会进行3次查询,因此它可以创建您可靠概述的结构

最终,这是一种折衷,第一个选项速度更快,但在php中,响应更难处理,因为php创建的代码可读性较差

我建议您使用内置的查询日志查看每个用户执行的查询

\DB::enableQueryLog();
$builtQuery->get()
dd(\DB::getQueryLog());

第一个是利用query builder more并执行一个查询,该查询如下所示:

SELECT * FROM answer
RIGHT JOIN questions ON answers.id_question = questions.id_question
LEFT JOIN users ON answers.id_user = users.id
WHERE questions.id_question = $id_question
AND questions.flg_active = true
ORDER BY questions.created_at desc
OFFSET 0
LIMIT 15
SELECT * FROM answer
ORDER BY created_at desc
OFFSET 0
LIMIT 15

SELECT * FROM question
WHERE answer_Id IN ($answer_ids) // Will be like (1, 5, 6, 7). All the ids retrieve from the first query

SELECT * FROM user
WHERE queston_id IN ($user_ids)
此查询将从所有表中返回数据,这些数据正是sql计算数据的方式。Laravel/Eloquent不知道如何将其可靠地转换为雄辩的格式

第二个将执行3个查询,如下所示:

SELECT * FROM answer
RIGHT JOIN questions ON answers.id_question = questions.id_question
LEFT JOIN users ON answers.id_user = users.id
WHERE questions.id_question = $id_question
AND questions.flg_active = true
ORDER BY questions.created_at desc
OFFSET 0
LIMIT 15
SELECT * FROM answer
ORDER BY created_at desc
OFFSET 0
LIMIT 15

SELECT * FROM question
WHERE answer_Id IN ($answer_ids) // Will be like (1, 5, 6, 7). All the ids retrieve from the first query

SELECT * FROM user
WHERE queston_id IN ($user_ids)
Eloquent会进行3次查询,因此它可以创建您可靠概述的结构

最终,这是一种折衷,第一个选项速度更快,但在php中,响应更难处理,因为php创建的代码可读性较差

我建议您使用内置的查询日志查看每个用户执行的查询

\DB::enableQueryLog();
$builtQuery->get()
dd(\DB::getQueryLog());

这是因为在你的第二个查询中,你利用你的雄辩的关系。Eloquent模型的默认
toArray()
方法将其属性和加载的关系合并到一个表示中

另一方面,第一个查询连接表,但不加载任何关系。因此,最直接的方法是在第一个查询中加载这些关系,就像在第二个查询中一样:

    $questions = \App\Answer::with('questions.user')           
        ->rightJoin('questions','answers.id_question','=','questions.id_question')
        ->leftJoin('users','answers.id_user','=','users.id')->where([
            ['questions.id_question', '=', $id_question],
            ['questions.flg_active', '=', true],
        ])->orderBy('questions.created_at', 'desc')->paginate(5);

请注意,这将产生额外的
SELECT。。。其中,(…)
中的id查询
问题
用户
模型,希望将其加载到各自的关系中。

这是因为在第二次查询中,您利用它们来建立雄辩的关系。Eloquent模型的默认
toArray()
方法将其属性和加载的关系合并到一个表示中

另一方面,第一个查询连接表,但不加载任何关系。因此,最直接的方法是在第一个查询中加载这些关系,就像在第二个查询中一样:

    $questions = \App\Answer::with('questions.user')           
        ->rightJoin('questions','answers.id_question','=','questions.id_question')
        ->leftJoin('users','answers.id_user','=','users.id')->where([
            ['questions.id_question', '=', $id_question],
            ['questions.flg_active', '=', true],
        ])->orderBy('questions.created_at', 'desc')->paginate(5);

请注意,这将产生额外的
SELECT。。。其中,(…)
查询
问题
用户
模型中的id将被急切加载到各自的关系中。

使用急切加载更新了这两个查询,但使用了(['Question','User'])。现在,第一个从问题中检索用户,而第二个从答案(我想要的)中检索用户。为什么?@Paulo您的加入可能会打乱急切的加载,因为答案表和问题表都有
id\u user
列(您通过它加入)。将
->select('answers.*)
添加到您的第一个查询中(其中
answers
是您的表的名称)。使用急切加载更新两个查询,但使用(['question','user'])。现在,第一个从问题中检索用户,而第二个从答案(我想要的)中检索用户。为什么?@Paulo您的加入可能会打乱急切的加载,因为答案表和问题表都有
id\u user
列(您通过它加入)。将
->select('answers.*)
添加到第一个查询中(其中
answers
是表名)。