Laravel如何将两个查询结果合并为单个对象

9
我目前卡在如何将两个查询结果合并为一个对象上。以下是我的代码。
编辑后的代码:
模型方法
public static function getTeamStats($competitionId, $teamId) {
    return TeamCompetitionStatistics::where('competitionId', $competitionId)
        ->where('teamid', $teamId)
        ->where('periodNumber', 0)
        ->get();
}

public static function getTeamPosition($competitionId, $teamId){
    return self::where('latest', 1)
        ->where('competitionId',$competitionId)
        ->where('competitorId', $teamId)
        ->get(['position', 'streak'])
        ->map(function($item, $key){
            $item->position = $item->position . date("S", mktime(0, 0, 0, 0, $item->position, 0));
            if(strpos($item->streak, '-') !== FALSE) {
                $item->streak = str_replace('-', 'L', $item->streak);
            }
            else {
                $item->streak = 'W'.$item->streak;
            }
            return $item;
        });
}

在控制器中获取数值
$teamStanding = Ladder::getTeamPosition($request->competitionId, $request->id);
$teamStatistics = TeamCompetitionStatistics::getTeamStats($request->competitionId, $request->id);

$result = $teamStatistics->merge($teamStanding);
[{'teamstanding': 'data', 'teamstatictics': 'data'}] 是期望的输出结果,而 [{'teamstanding': 'data'}, {'teamstatictics': 'data'}] 是现有的返回结果。需要将两个字典合并为一个字典,最终的结果符合期望的格式。

你可以这样使用:$array = array_merge($teamStanding->toArray(), $teamStatistics->toArray()); return Response::json($array); - Hiren Gohel
@PenAndPapers 看看这个:https://laravel.com/docs/5.4/collections#method-merge - Nikhil Radadiya
@PenAndPapers 這對你來說適用嗎? - Hiren Gohel
@HirenGohel 它仍然返回一个数组中的两个对象 - PenAndPapers
4个回答

34

你可以使用 all() 函数。

$teamStanding = Ladder::getTeamPosition($request->competitionId, $request->id)->get();

$teamStatistics = TeamCompetitionStatistics::getTeamStats($request->competitionId, $request->id)->get();

$merged = $teamStatistics->merge($teamStanding);

$result = $merged->all();

// return [{'teamstanding': 'data', 'teamstatictics': 'data'}]

它仍然返回一个包含两个对象的数组。 - PenAndPapers
我已经编辑了我的代码,我认为你需要使用get()函数。 - Jakir Hossain
2
我更新了我的代码并添加了来自我的 Model 的方法。我尝试了您的解决方案,但不起作用。 - PenAndPapers
1
你能使用 merge($query,$query,...) 吗?如果你需要做3-4个怎么办? - levi

7

尝试使用merge()

merge方法将给定的数组或集合与原始集合合并。

$first = ModelName::where('<fieldName>','<searchText>')
        ->get();
$second = Album::where('<fieldName>','<searchText>')
    ->get();

$finalResult = $first->merge($second);

$finalResult->each(function($record)
{
    echo $record-><fieldName>.'<br />';
});

6

由于之前的解决方案并不能很好地适用于我,因为两个对象只是被添加到了同一个数组中:{"Name":"A Name"},{"Surname":"A Surname"}。我不得不收集我的数组并使用first方法。

https://laravel.com/docs/5.4/collections#method-merge

$first  = $modelone->where('Id', '1')->first(['Name']);
$second = $modeltwo->where('Thing', '1')->first(['Surname']);

    $collection = collect($first);
    $merged     = $collection->merge($second);
    $result[]   = $merged->all();
    return $result;
//output: [{"Name":"A Name","Surname":"A Surname"}]

这是最好的答案。它解决了我已经寻找了几周的问题。谢谢。 - John

4

个人而言,我不喜欢将两个可能的大查询转换为集合并进行合并,这似乎会有很多处理。

我通常使用union(),也许这可以帮助其他人。 Laravel的联合文档

$first = DB::table('users')
        ->whereNull('first_name');

$users = DB::table('users')
        ->whereNull('last_name')
        ->union($first)
        ->get();

合并(merge)函数是否也适用于分页(paginate)?例如,我们能否像这样使用 $merged->paginate(10) 进行操作? - Skykid Felix
在我的项目中,我正在使用Fractal作为我的转换器,并通过将项目添加到Fractal Collection中来实现它$collection = new Collection($items, $transformer, $type);,然后将其添加到来自Fractal的IlluminatePaginatorAdapter中$collection->setPaginator(new IlluminatePaginatorAdapter($items));如果您可以使用Fractal完成此操作,则Laravel也必须有一种方法。 - NinetyHH
谢谢,我会尝试的。我的目标是创建一个类似Facebook的新闻动态,其中包含多个模型(帖子、视频、状态、投票)。现在我想将它们合并,并可能对它们进行混洗,以便每个模型结果不是分组的。最后再进行分页。 - Skykid Felix
这更多是个人偏好,但从我的角度来看,这听起来相当昂贵。我将创建一个类型为Post(数据库中的帖子)的对象,它具有默认列,但可以与视频实体、池实体等相关联,然后大部分情况下只需要正确的关系,例如hasMany等。因此,不必进行大量查询和合并所有数据,只需返回标准化的Posts转换器,其中包括基于可用外键的关系。通过这种方式,您将不需要合并任何查询。 - NinetyHH
由于我每次分页处理10个结果,因此我认为我不需要担心处理时间,对吧?我刚开始接触Laravel的Eloquent关联,而我的数据库已经包含了用户生成的内容,所以我现在不能采用那种方法。你能否向我展示一下你使用分页适配器的代码片段?非常感谢。 - Skykid Felix

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接