【问题标题】:Laravel - Paginate with mysql Rand() and SeedLaravel - 使用 mysql Rand() 和 Seed 进行分页
【发布时间】:2019-11-01 00:40:00
【问题描述】:

我几乎要放弃了,因为我已经坚持了很长时间。 希望你能帮帮我。

目标

我想在无限滚动中返回一个分页和缓存的查询。 我正在使用 Ajax 从视图调用控制器并获取“nextPageUrl()”并将其保存在我的视图中。

问题

我的查询返回内部数组的随机顺序(也按第一级排序),这很棒。但是每次我进行 ajax 调用时查询都会运行。所以我想:嘿,让我们缓存它,这样我每次进行 ajax 调用时都有相同的查询,而且我没有更多的重复项。但是我做的每一个ajax请求都会出现重复..

我尝试了什么:

这是我的缓存和分页查询:

$counter = $request->page;

$results = Cache::remember($counter, 1, function () {
    $seed = rand(1,9999);

    return Ad::where('status', 1)
        ->whereIn('ad_type', [0, 1, 2, 3])
        ->where('expire_at', '>', date('Y-m-d H:i:s'))
        ->where('special_ad', 'standard_ad')
        ->orderByRaw(DB::raw("FIELD(ad_type,2,1,3,0)"))
        ->inRandomOrder()
        ->paginate(15);
});


if($request->ajax()) {
    return [
        'ads' => view('partials.advanced_search_sidebar2')->with(compact('results','index'))->render(),
        'next_page' => $results->nextPageUrl(),
    ];
} else {
    return view("welcome_live", compact('results', 'usertypes'));
}

inRandomOrder(); 方法是 laravel 等价于 orderByRaw("RAND()")

我发现以下内容不幸地不适用于我: Laravel Random Pagination Cache

我不想写太多,因为如果您需要更彻底的代码解释或更多代码 sn-ps 或我的“处理方式解释”,这里的代码墙可能会令人困惑请告诉我。 预先感谢您对我们的支持。 问候,Desory。

编辑:: 我尝试在 inRandomOrder($seed) 中使用 $seed 作为参数,但这会一遍又一遍地返回相同的查询,即使种子不同。

更接近解决方案 我尝试使用固定的 $seed 值,在我的情况下,我只是输入了 25 所以种子总是 25,不再重复,很好,但现在的顺序总是一样的。 我基本上觉得我可以选择随机顺序和重复,以及具有相同顺序但不重复..

我的 Ajax 函数

function renderBase() {
    var page = $('.suchergebnisWrapper').data("base");
    var counter = $('.suchergebnisWrapper').data("counter");


    if (counter < 10) {
        $.ajax({
            url: page,
            type: 'GET',
            data: {
            },
            headers: {
                'X-CSRF-Token': '{{ csrf_token() }}',
            },
        }).done(
            function (responseData) {
                $('.resultwrapper').append(responseData.ads);
                $('.suchergebnisWrapper').data('base', responseData.next_page);

            });
    }

}

这可能看起来令人困惑,因为在控制器中我使用“计数器”和 javascript,但这只是每次在我的缓存中都有一个不同的“键”。

【问题讨论】:

  • 对我来说,您应该在用户会话中定义您的$seed,以便始终为给定用户使用相同的$seed。在您的示例中,每次缓存查询时,都会得到一个新的$seed,因此是一个新订单。然后,您确定在您的 ajax 调用中传递了 page 参数吗?
  • 我将尝试将种子存储在用户会话中,感谢您的建议。当我运行此查询时,我得到一个新订单,这正是我需要的。每次缓存重置时都会出现一个新订单。我将在我最初的问题的编辑中发布我的 ajax 函数。感谢您到目前为止提供的帮助 Vincent Decaux。
  • 我看不出有任何方法可以以简单的方式实现您的愿望。由于您希望始终随机排序,因此您不能以任何有意义的方式使用 Laravel 分页,因为分页的目的是将结果集拆分为可以一次显示的更小的块。但是随机化结果基本上可以确保迟早你会得到重复,因为分页器不知道你的查询做了什么,它只是返回一个块。
  • 为了避免重复但在无限滚动页面中保持结果的随机性,每次返回结果集块时执行的查询应该知道排除已经呈现的结果。虽然这看起来很简单,但每次您缓存更多标识符(或您需要的任何数据)以过滤掉已经呈现的结果时,您的查询将不可避免地变慢,因为它需要过滤掉越来越大的结果集。
  • 我看不到任何其他合乎逻辑的方法来确保没有返回重复项并且每次仍然运行随机查询。您的查询必须包含某种在查询运行时防止重复的条件。显而易见的方法是标识符,也许可以为特定情况找到一些其他策略,但尝试缓存查询结果对于这个特定问题似乎不合逻辑。

标签: mysql laravel caching queue


【解决方案1】:

distinct() 可以给你不重复的数据,你应该在其中传递像 id 这样的属性

return Ad::where('status', 1)
    ->whereIn('ad_type', [0, 1, 2, 3])
    ->where('expire_at', '>', date('Y-m-d H:i:s'))
    ->where('special_ad', 'standard_ad')
    ->orderByRaw(DB::raw("FIELD(ad_type,2,1,3,0)"))
    ->inRandomOrder()
    ->distinct()
    ->paginate(15);

【讨论】:

  • 确实是个好主意,但我已经尝试过了。如果它是一个静态查询,它将完美地工作,但它是非常动态的,也就是说,查询可能看起来像:[1,2,4,3,10] 并且在下一次运行中 [10,100,291,3,1]。我真的不知道为什么 distinct 不能正常工作,tbh,但这并不是我所知道的全部。感谢您为帮助我所做的努力。
【解决方案2】:

在 $counters->appends(Input::except('page')); 之后试试这个;

【讨论】:

  • 我很抱歉,你到底是什么意思:)?
  • @Dinesh Bajgain 答案应该包含解释。粘贴一行代码并不是很有用,被认为质量很低。
  • 返回视图中的值之前
  • 我认为你误解了这个问题。并非整个页面都重复,但由于随机性,我的查询中的某些结果会重复。
  • 这行代码追加数据并删除之前的分页链接
猜你喜欢
  • 1970-01-01
  • 2011-07-18
  • 2012-03-27
  • 1970-01-01
  • 1970-01-01
  • 2020-03-18
  • 2014-09-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多