使用 Eloquent 的 Laravel 块方法

Posted

技术标签:

【中文标题】使用 Eloquent 的 Laravel 块方法【英文标题】:Laravel Chunk Method Using Eloquent 【发布时间】:2017-02-19 17:22:18 【问题描述】:

对于大型数据库的处理,laravel 提供了这里的 chunk 方法https://laravel.com/docs/5.1/queries#retrieving-results

但是我如何在这个查询中使用块方法,

 $data = Inspector::latest('id')
                ->select('id', 'firstname', 'status', 'state', 'phone')
                ->where('firstname', 'LIKE', '%' . $searchtext . '%')
                ->get();

我在哪里返回这样的 json 响应,

echo json_encode($data);

任何建议....

【问题讨论】:

【参考方案1】:

使用chunk() 代替get()。 例如。 chunk(100, function($data) )

【讨论】:

如何在视图上使用它? @Praditha 不要在视图中使用这样的东西,这是一个非常糟糕的做法【参考方案2】:

据我了解,chunk() 方法适用于您需要处理大型数据集并对数据块逐块采取行动

从您的问题来看,听起来您正在执行查询,然后将数据作为 JSON 返回,所以对我来说,这听起来不像您正在对需要分块的数据集执行操作。

如果您想分解返回的 JSON 数据,您应该查看 pagination。

您可以像这样对查询应用分页:

$data = Inspector::latest('id')
    ->select('id', 'firstname', 'status', 'state', 'phone')
    ->where('firstname', 'LIKE', '%' . $searchtext . '%')
    ->paginate();

您可以通过向 paginate 方法传递一个数字来指定每个集合的大小:

$data = Inspector::latest('id')
    ->select('id', 'firstname', 'status', 'state', 'phone')
    ->where('firstname', 'LIKE', '%' . $searchtext . '%')
    ->paginate(25);

如果我误解了并且您确实想要进行分块,我相信您可以执行以下操作:

$data = Inspector::latest('id')
    ->select('id', 'firstname', 'status', 'state', 'phone')
    ->where('firstname', 'LIKE', '%' . $searchtext . '%')
    ->chunk(50, function($inspectors) 
        foreach ($inspectors as $inspector) 
            // apply some action to the chunked results here
        
    );

此外,如果您要返回一个 eloquent 对象,它将自动转换为 json,因此据我所知,您无需执行 json_encode()

编辑

如果我完全误解了你,而你真正想要做的是:

 1000 records  -> this is the result of your query

拆分成这样:


     300 records,
     300 records,
     300 records,
     100 records,

那你想要Collection的chunk方法:

$data = Inspector::latest('id')
    ->select('id', 'firstname', 'status', 'state', 'phone')
    ->where('firstname', 'LIKE', '%' . $searchtext . '%')
    ->get() // now we're working with a collection
    ->chunk(300);

请记住,在您获得查询结果之前,您不会使用Collection,因此如果您只是调用chunk(),它将期待一个回调,该回调将应用于整个数据集,因为您正在工作Eloquent

在此处查看Collection chunk() 方法的进一步阅读:https://laravel.com/docs/5.3/collections#method-chunk

否则...您能否为您实际在做的事情提供更多背景信息?听起来你真的需要分页。你在用 JSON 数据做什么,你是如何调用 HTTP 请求的,是通过 ajax 吗?为什么一次需要全部 1000 条记录?

如果您确实需要将 1000 个的整个数据集发送到客户端,但一次 300 个,那么您不想使用块。想想chunk() 在 eloquent 的上下文中的用途,它不是为了让块一次返回一个块,直到它拥有整个数据集 - 它是为了对块应用一个动作然后返回整个数据集并且使用它的目的是通过加载整个集合来处理操作,一次不会占用太多内存。

如果您希望逐位获取整个数据集并且分页不适用于您的情况(我还没有明白为什么!)您将需要多次调用 HTTP 请求以逐位获取数据,然后在每个请求中指定您已经拥有的和需要的。

【讨论】:

我已经尝试了第三个答案,这是正确的,但我的问题是,如果我想显示 1000 条记录,但它应该在 300 条记录的范围内发送。像第一个 300 然后 300 然后 300 ,作为json响应。但不是一次一千个。 非常感谢..我现在明白了。 :) @Aamir 太棒了!快乐编码 @haakym 也许你可以帮助我。我想为我的案例实现块。看看这个:***.com/questions/51487769/… chunk() 方法适用于 Laravel 4 和 5。对于 Laravel 4,它有一个可选的第二个参数来保留键,默认为 false,当我检查 5.7 集合参考时它被删除。 【参考方案3】:
    可以使用变量$counter并放
if ($counter>=100)  break; 
    可以在视图中调用
use path/models/User;
Users->chunk(100, function($users) 
    foreach ($users as $user) 
        //
    
);

【讨论】:

【参考方案4】:

Chunk 不是用于通过请求返回数据,而是用于处理服务器上的大型表 - 这是一个简单的示例,展示了如何使用它(在 Laravel 5.7 上测试):

User::chunk(100, function($users) 
    foreach ($users as $user) 
        // processing
    
);

【讨论】:

“为 foreach() 提供的参数无效” 好的@Kamil谢谢这是嵌套foreach循环中的问题,而不是父循环。

以上是关于使用 Eloquent 的 Laravel 块方法的主要内容,如果未能解决你的问题,请参考以下文章

在块函数 Laravel 上使用变量

Laravel Eloquent - orWhereHas 方法 - 何时使用以及如何使用

Laravel/Eloquent 建议覆盖 trait 属性?

php [Eloquent CheatSheet] Eloquent #laravel #eloquent的常见查询方法

将 whereIn() 方法与 laravel Eloquent 模型一起使用

Laravel Eloquent 关系方法语法