我有一个 laravel 应用程序,它显示一个带有数据表的表格。我正在使用服务器端数据表,数据集有超过 15k 行

Posted

技术标签:

【中文标题】我有一个 laravel 应用程序,它显示一个带有数据表的表格。我正在使用服务器端数据表,数据集有超过 15k 行【英文标题】:I have a laravel app that displays a table with Datatables. I am using serverSide Datatables, the dataset has morethan 15k rows 【发布时间】:2021-12-07 21:52:00 【问题描述】:

我有一个 laravel 应用程序,它显示一个带有 YajraDatatable 的表,数据是从 mongoDB 中获取的。我正在使用服务器端数据表,数据集有超过 20k 行。它真的很慢,给我错误 500 服务器错误。如果我使用限制为 50000 则一切正常,并且每页 100 条记录或 10 条记录页需要时间。

/* 控制器功能 */

            $certificates =  DatatableUtils::checkRole('AddJob')
                ->with('fittingType:name')
                ->with('company:name')
                ->with('hosType:name')
                ->with('location')
                ->where('isScraped',false)
                ->select('created_at', 'trackingNumber', 'unit', 'location_id', 'diameterNumber', 'lengthFeet', 'lengthInch', 'hawpPsi', 'job_status', 'fittingId','hoseTypeId','companyId','image')
                ->orderBy('created_at','desc');
            return Datatables::of($certificates)->addIndexColumn()
                ->filter(function ($instance) use ($request) 
                    DatatableUtils::searchColumn($request, $instance);

                    /* Main filter */
                    DatatableUtils::mainFilter($request, $instance);
                )
                ->editColumn('staticTestDate', function($row)
                    return date('d/M/Y', strtotime($row->staticTestDate));
                )
                ->editColumn('image', function($row)
                    return DatatableUtils::getImg($row);
                )
                ->editColumn('staticReTestDate', function($row)
                    return date('d/M/Y', strtotime($row->staticReTestDate));
                )

                ->addColumn('date_created', function($row)
                    return $row->created_at;
                )
                ->editColumn('status', function($row)
                    $status = '';
                    for ($i = 0; $i < $row->job_status; $i++)
                        $status =  $status.'<div class="glyph">
                             <div class="glyph-icon simple-icon-star ml-1"></div>
                         </div>';
                    
                    return '<div class="display-ruby">'.$status.'</div>';
                )
                ->addColumn('length', function($row)
                    return $row->lengthFeet .' / ' . $row->lengthInch;
                )
                ->addColumn('action', function($row)
                    return '<a href="'.route('certificates.show', $row['_id']).'" class="edit btn btn-outline-primary btn-sm">View</a>';
                )
                ->rawColumns(['status','Length', 'reasons', 'action','date_created'])
                ->make(true);
        

/* 数据表通用函数 */

    const columnsName = [];
    if (createdRow)
        $("#"+id+ " thead tr th").each(function(index)
            columnsName.push(this.innerhtml);
        );
    
    const table = $("#"+id).DataTable(
        bLengthChange: false,
        processing: true,
        serverSide: true,
        pageLength: 10,
        ajax: 
            url: url,
            type: "get",
            dataType: "json",
            data: function (d) 
                // filters
                d.dateFilterMain     = $('#dateFilterMain').val()
                d.statusFilterMain   = $('#statusFilterMain').val()
                d.companyFilterMain  = $('#companyFilterMain').val()
                d.locationFilterMain = $('#locationFilterMain').val()
                d.YearFilterMain     = $('#YearFilterMain').val()
                d.companyFilter      = $('#companyFilter').val()

                // company filter location
                d.cFilterLocation    = $('#cFilterLocation').val()

                // searches
                d.searchDate         = $('#searchDate').val();
                d.searchCompany      = $('#searchCompany').val();
                d.searchType         = $('#searchType').val();
                d.searchUnit         = $('#searchUnit').val();
                d.searchLocation     = $('#searchLocation').val();
                d.searchStatus       = $('#searchStatus').val();
                d.searchTracking     = $('#searchTracking').val();
                d.searchFittings     = $('#searchFittings').val();
                d.searchRepairedBy   = $('#searchRepairedBy').val();

                // reasons searches
                d.searchFitting      = $('#searchFitting').val();
                d.searchClamp        = $('#searchClamp').val();
                d.searchTube         = $('#searchTube').val();
                d.searchCover        = $('#searchCover').val();

                // searches company
                d.cSearchDate        = $('#cSearchDate').val();
                d.cSearchName        = $('#cSearchName').val();
                d.cSearchCode        = $('#cSearchCode').val();
                d.cSearchSRetest     = $('#cSearchSRetest').val();
                d.cSearchHRetest     = $('#cSearchHRetest').val();
                d.cSearchVRetest     = $('#cSearchVRetest').val();
                d.cSearchNextNumber  = $('#cSearchNextNumber').val();
                d.cSearchEmail       = $('#cSearchEmail').val();
                d.cSearchPhone       = $('#cSearchPhone').val();


                // searches company user
                d.cUserName          = $('#cUserName').val();
                d.cUserEmail         = $('#cUserEmail').val();
                d.cUserPhone         = $('#cUserPhone').val();
                d.cUserCompany       = $('#cUserCompany').val();
                d.cUserStatus        = $('#cUserStatus').val();

                // searches location
                d.searchLocationName = $('#searchLocationName').val();
                d.searchLocationCode = $('#searchLocationCode').val();
                d.searchLocationNum  = $('#searchLocationNum').val();

                d.searchHoseName     = $('#searchHoseName').val();

                // searches fitting
                d.searchFittingName       = $('#searchFittingName').val();
                d.searchFittingDiam       = $('#searchFittingDiam').val();
                d.searchFittingType       = $('#searchFittingType').val();
                d.searchFittingVendor     = $('#searchFittingVendor').val();
            
        ,
        createdRow: function (row, data, dataIndex) 
            $(row).find('td').addClass('text-center');
            if (createdRow) 
                $.each(columnsName, function (key, column) 
                    if (column === data.month) 
                        $(row).find('td:eq(' + (parseInt(key) - 1) + ')').text(data.date);
                        $(row).find('td:eq(' + (parseInt(key) - 1) + ')').addClass(data.badge);
                    
                );
            
        ,
        columns: dataColumns,
        buttons: [
            'copy',
            'excel',
            'csv',
            'pdf'
        ],
        destroy: true,
        info: false,
        sDom: '<"row view-filter"<"col-sm-12"<"float-left"l><"float-right"f><"clearfix">>>t<"row view-pager"<"col-sm-12"<"text-center"ip>>>',
        columnDefs: [
             "orderable": false, "targets": 0 
        ],
        language: 
            paginate: 
                previous: "<i class='simple-icon-arrow-left'></i>",
                next: "<i class='simple-icon-arrow-right'></i>"
            
        ,
        drawCallback: function () 
            $($(".dataTables_wrapper .pagination li:first-of-type")).find("a").addClass("prev");
            $($(".dataTables_wrapper .pagination li:last-of-type")).find("a").addClass("next");
            $(".dataTables_wrapper .pagination").addClass("pagination-sm");
            const api = $(this).dataTable().api();
            $("#pageCountDatatable span").html("Displaying " + parseInt(api.page.info().start + 1) + "-" + api.page.info().end + " of " + api.page.info().recordsTotal + " items");
        
    );
    // filter
    $('#companyFilter').on('change', function () 
        table.draw();
     )
    $('#cFilterLocation').on('change', function () 
        table.draw();
     )
    // searches
    $("#searchDate").on("keyup", function() 
        table.draw();
    );
    $('#searchTracking').on( 'keyup', function () 
        table.draw();
     )
    $('#searchCompany').on( 'keyup', function () 
        table.draw();
     )
    $('#searchUnit').on( 'keyup', function () 
        table.draw();
     );
    $('#searchLocation').on( 'keyup', function () 
        table.draw();
     )
    $('#searchType').on( 'keyup', function () 
        table.draw();
     )
    $('#searchStatus').on( 'keyup', function () 
        table.draw();
     )
    $('#searchFittings').on( 'keyup', function () 
        table.draw();
     )
    $('#searchRepairedBy').on( 'keyup', function () 
        table.draw();
     )

    $('#searchFitting').on( 'keyup', function () 
        table.draw();
     )
    $('#searchCover').on( 'keyup', function () 
        table.draw();
     )
    $('#searchTube').on( 'keyup', function () 
        table.draw();
     )
    $('#searchClamp').on( 'keyup', function () 
        table.draw();
     )

    // company searches
    $('#cSearchDate').on( 'keyup', function () 
        table.draw();
     )
    $('#cSearchName').on( 'keyup', function () 
        table.draw();
     )
    $('#cSearchCode').on( 'keyup', function () 
        table.draw();
     )
    $('#cSearchSRetest').on( 'keyup', function () 
        table.draw();
     )
    $('#cSearchHRetest').on( 'keyup', function () 
        table.draw();
     )
    $('#cSearchVRetest').on( 'keyup', function () 
        table.draw();
     )
    $('#cSearchNextNumber').on( 'keyup', function () 
        table.draw();
     )
    $('#cSearchEmail').on( 'keyup', function () 
        table.draw();
     )
    $('#cSearchPhone').on( 'keyup', function () 
        table.draw();
     )

    // searches company user
    $('#cUserName').on( 'keyup', function () 
        table.draw();
     )
    $('#cUserEmail').on( 'keyup', function () 
        table.draw();
     )
    $('#cUserPhone').on( 'keyup', function () 
        table.draw();
     )
    $('#cUserCompany').on( 'keyup', function () 
        table.draw();
     )
    $('#cUserStatus').on( 'keyup', function () 
        table.draw();
     )

    // searches location
    $('#searchLocationNum').on( 'keyup', function () 
        table.draw();
     )
    $('#searchLocationCode').on( 'keyup', function () 
        table.draw();
     )
    $('#searchLocationName').on( 'keyup', function () 
        table.draw();
     )

    // hose type search
    $('#searchHoseName').on( 'keyup', function () 
        table.draw();
     )

    // fitting type search
    $('#searchFittingVendor').on( 'keyup', function () 
        table.draw();
     )
    $('#searchFittingType').on( 'keyup', function () 
        table.draw();
     )
    $('#searchFittingDiam').on( 'keyup', function () 
        table.draw();
     )
    $('#searchFittingName').on( 'keyup', function () 
        table.draw();
     )

    $("#pageCountDatatable .dropdown-menu a").on("click", function(event) 
        const selText = $(this).text();
        table.page.len(parseInt(selText)).draw();
    );
    $('#btnFilterSubmit').click(function()
        table.draw();
    );
    $('table thead tr').find('th').addClass('text-center');

【问题讨论】:

您是否查看过任何也支持服务器端处理的 Yajra 包?这是one example(警告:我没有使用它)-我希望还有其他人。 Stack Overflow 上有 related questions 可能也有帮助。 【参考方案1】:

在 MongoDB 中使用 YajraDatatable 时。我们必须将 post 数据 'start' 和 'length' 的类型从 string 转换为 int。

我们必须在调用 YajraDatatable 之前进行这种类型转换。

$request->merge(array( 
    'start' => (int)$request->input('start'), 
    'length' => (int)$request->input('length') 
));

【讨论】:

谢谢你,你让我开心:)【参考方案2】:

显然 YajraDatatable 不太适合大数据。相反,您应该使用-&gt;paginate() 方法创建自己的表。您可以使用 Jquery 进行更动态的编写。

【讨论】:

那不好。 :( 当您使用 YajraDatatable 时,它​​会在一个请求中加载大量数据。但如果你能正确实现它,也许 Voucher 可以帮助你。 我什么都试过了 :( 因此,使用分页和 jquery 编写您自己的表格(如 yajra)并不难。我敢肯定它比 yajra 更耐用 我知道,但我没有足够的时间来更改所有数据表功能。

以上是关于我有一个 laravel 应用程序,它显示一个带有数据表的表格。我正在使用服务器端数据表,数据集有超过 15k 行的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 和谷歌地图:foreach 纬度/经度显示标记或地图

如何使用 vuejs 在 laravel 刀片中显示验证错误

带有输入表单的 Laravel 路由视图

带有 laravel 后端数据的 Vue v-if

Laravel 4 - 显示带有旧数据输入以及数据库信息的编辑表单

使用 laravel 向 api 发出多个请求