Laravel - แบ่งหน้าบันทึกแบบสุ่ม

เราจะแบ่งหน้าผ่านบันทึกแบบสุ่มใน laravel ได้อย่างไร ตัวอย่างเช่น:

$products = Product::all()->orderBy(DB::raw('RAND()'));
$products->paginate(4);
$products->setPath('products');

ด้านบนจะลงท้ายด้วยบันทึกที่ซ้ำกัน เนื่องจากการเรียงลำดับแบบสุ่ม ฉันจะคงวัตถุ $products ไว้ได้อย่างไรเพื่อที่เมื่อมีการร้องขอเพจใหม่ มันควรกรองชุดบันทึกแบบสุ่มที่เหมือนกัน/คงที่


person dang    schedule 31.05.2016    source แหล่งที่มา
comment
โปรดบอกเราว่าคุณได้ลองใช้อะไรไปแล้วบ้างและสิ่งใดที่ไม่ได้ผล   -  person Alexandre Cartapanis    schedule 31.05.2016
comment
@AlexandreCartapanis - การแบ่งหน้าให้บันทึกที่ซ้ำกัน เราใช้โค้ดข้างต้น   -  person dang    schedule 31.05.2016


คำตอบ (3)


เมื่อคุณเจาะลึกเอกสารประกอบของ mysql และ ค้นหาฟังก์ชัน RAND() คุณจะเห็นว่าคุณสามารถใช้ "seed" ได้

โดยการใช้เมล็ดพืช คุณจะได้รับผลลัพธ์แบบเดียวกับที่ถูกสุ่มเสมอ

ตัวอย่าง:

$products = Product

    ::all()

    ->orderBy(DB::raw('RAND(1234)'))

    ->paginate(4);

คุณสามารถสร้างเมล็ดพันธุ์ของคุณเองและเก็บไว้ในเซสชั่นหรือบางอย่างเพื่อจดจำได้

อัปเดต

ขณะนี้ ตัวสร้างคิวรี Laravel มีฟังก์ชันที่ทำงานได้จริงทุกประการ เหมือน:

$products = Product

    ::all()

    ->inRandomOrder('1234')

    ->paginate(4);
person Thomas Van der Veen    schedule 31.05.2016
comment
+1. เนื่องจากฉันไม่ได้ใช้ Eloquent ฉันรู้สึกโชคดีที่พบว่าฟังก์ชันตัวช่วย Collection shuffle ยัง อนุญาตให้ใช้พารามิเตอร์ seed ได้ ซึ่งมีประโยชน์หากคุณใช้การแบ่งหน้าและต้องการป้องกันการซ้ำซ้อนในลำดับถัดไป หน้า: github.com/illuminate/support/blob/5.6/Collection php#L1380 - person Ryan; 24.06.2018

วิธีแก้ปัญหาด้วย Laravel + Eloquent

ก่อนการสืบค้น Eloquent ให้ตั้งค่าตัวแปรเซสชัน ฉันใช้เวลา () เป็นค่าเซสชัน ดังนั้นฉันจึงสามารถเก็บลำดับเดิมไว้เป็นระยะเวลาหนึ่งได้ เช่น 3,600 วินาที (1 ชั่วโมง)

if ($request->session()->has('session_rand')) {

    if((time() - $request->session()->get('session_rand')) > 3600){
        $request->session()->put('session_rand', time());
    }
}else{
    $request->session()->put('session_rand', time());
}

เพิ่ม ->orderBy() ลงในแบบสอบถาม Eloquent โดยใช้ DB::raw() และตัวแปรเซสชันที่เราตั้งค่าไว้ด้านบน:

->orderBy(DB::raw('RAND('.$request->session()->get('session_rand').')'))
person Darren Murphy    schedule 14.09.2018

โซลูชัน Ajax + ก้อน + เซสชัน + Lazyload + การแบ่งหน้า + ฝีปาก + เบลด

รับผลิตภัณฑ์ทั้งหมด กำหนดจำนวนรายการสำหรับแต่ละชิ้น (เช่นการแบ่งหน้า) และเก็บไว้ในเซสชัน (เราเก็บชิ้นส่วนไว้ในเซสชันดังนั้นเมื่อคำขอ ajax เข้ามามันจะไม่เรียก $products = Product::inRandomOrder()->get(); อีกครั้ง) ชิ้นแรกจะเป็นการแบ่งหน้าแรก

เมื่อ ajax ขอผลิตภัณฑ์เพิ่มเติม ก็จะได้รับผลิตภัณฑ์จากเซสชัน และรับกลุ่มผลิตภัณฑ์ที่ถูกต้องตามหมายเลขหน้า ajax ที่ร้องขอ

หากไม่มีชิ้นเหลือก็ส่งคืนโดยไม่มีสินค้าใดๆ

    if(!$request->ajax()){

        $products = Product::inRandomOrder()->get();
        $chunks = $products->chunk(4);

        \Session::put('chunks',$chunks);
        $products = $chunks[0];
    }else{
        $page = $request->all()['page'];                
        $chunks = \Session::get('chunks');

        if(count($chunks)<$page){
            \Session::forget('chunks');
            return;
        }else{
            $products = $chunks[$page-1];
        }
    }

   if ($request->ajax()) {
        $view =  view('product_lazyLoad',compact('products'))->render();
        return response()->json(['html'=>$view]);
   }

   return view('products',compact('products'));

products.blade.php : หน้าหลัก

@if($products)
    <ul class="row" id="productLists">
        @include('product_lazyLoad')
    </ul>
@endif

<!-- load records -->

<div class="col-12 ajax-load text-center" style="display:none">
    <p><img src="/images/loader.gif">Loading More Products</p>
</div>

product_lazyload.blade.php : แสดงสินค้า

@foreach($products as $product)
    <div>
        <p>Display your products here</p>
    </div>
@endforeach

การเรียก ajax แบบอักษรสิ้นสุด : เมื่อเพจถูกเลื่อนไปที่ด้านล่างของหน้า หน้าตัวแปรจะเพิ่มขึ้นอัตโนมัติและขอแบ็กเอนด์สำหรับผลิตภัณฑ์เพิ่มเติม หากมีการคืนสินค้าเพิ่ม สินค้าจะผนวกสินค้าเข้ากับองค์ประกอบด้วย id = "productlist" ใน products.blade.php

    //lazy load
    var page = 1;
    $(window).scroll(function() {
        if($(window).scrollTop() + $(window).height() >= $(document).height()) 
        {
            page++;
            loadMoreData(page);
        }
    });

  function loadMoreData(page){
        $.ajax({
            url: '?page=' + page,
            type: "get",
            beforeSend: function(){
                $('.ajax-load').show();
            }
        }).done(function(data){
            if(!data.html){
                $('.ajax-load').html("No more records found");
                $('.ajax-load').show();
                return;
            }

            $('.ajax-load').hide();
            $("#productLists").append(data.html);

        }).fail(function(jqXHR, ajaxOptions, thrownError){
             //error handle
        });
    }
person Jason    schedule 17.12.2018