Vážené skóre a trendy
Dva scopy na zoradenie idú nad rámec obyčajných počtov:
Post::orderByLikeScore()->get(); // rank by a weighted sum of reactions (desc)
Post::orderByTrending()->get(); // rank by recency-weighted activity (desc)
Post::orderByLikeScore('asc')->get();
Post::orderByTrending('desc', 'love')->get(); // trending lovesVážené skóre
orderByLikeScore() zoraďuje podľa váženého súčtu reakcií z config('likes.weights'). Pri predvolenom nastavení (bez váh) sa skóre rovná obyčajnému počtu páčikov. Niektorým reakciám dajte väčšiu váhu:
// config/likes.php
'weights' => ['like' => 1, 'love' => 4],
'default_weight' => 1,Keď weights nie je prázdne, každá neuvedená reakcia použije default_weight.
Trendy
orderByTrending() vypočíta pre každý riadok skóre ako nedávna vážená aktivita × recent_multiplier + celková vážená aktivita, pričom nedávna znamená vytvorená v rámci trending.window. Hranica okna sa počíta v PHP a odovzdáva ako viazaný parameter, rovnako ako všetky váhy — SQL tak zostáva prenosné medzi SQLite, MySQL a PostgreSQL a odolné voči injekcii.
// config/likes.php
'trending' => [
'window' => '3 days', // what counts as "recent"
'recent_multiplier' => 5, // recent likes weigh 5x on top of all-time activity
'driver_expressions' => [],
],Čítanie skóre
Každý scope pridá skóre do riadku — like_score alebo trending_score — takže ho môžete zobraziť alebo si overiť poradie:
$top = Post::orderByLikeScore()->first();
$top->like_score; // the weighted score the rows were ranked by
$hot = Post::whereNotLikedBy($user)->orderByTrending()->limit(10)->get();
$hot->first()->trending_score;Oba scopy prijímajú smer (asc alebo desc — čokoľvek iné zoraďuje zostupne) a voliteľný typ reakcie, ignorujú odobraté páčiky a skladajú sa s ďalšími scopmi.
Výrazy pre konkrétny driver
Ak chcete presnú krivku útlmu, nahraďte skóre trendov pre konkrétny databázový driver surovým SQL agregátom nad záznamami páčikov. orderByTrending() ho doslovne použije v dopytoch na spojení s týmto driverom — pre ostatné prenosný hybrid — a každý ? v ňom sa naviaže na hranicu okna (teraz mínus trending.window):
// config/likes.php
'trending' => [
'window' => '7 days',
'recent_multiplier' => 3,
'driver_expressions' => [
// Gravity: each like decays with its age in hours.
'pgsql' => 'SUM(1 / POWER(EXTRACT(EPOCH FROM (NOW() - created_at)) / 3600 + 2, 1.8))',
// Recent likes count 10x, bound to the window cut-off.
'sqlite' => 'SUM(CASE WHEN created_at >= ? THEN 10 ELSE 1 END)',
],
],Výraz je konfigurácia aplikácie, nikdy vstup od používateľa — do dopytu sa vloží tak, ako je napísaný. Ten istý výraz pre vlastné dopyty na zoradenie vráti TrendingScore::trending():
use RoundlyConsulting\Likes\Support\TrendingScore;
['expression' => $expression, 'bindings' => $bindings] = TrendingScore::trending(); // the likes model's driver
['expression' => $expression, 'bindings' => $bindings] = TrendingScore::trending('pgsql');
// your driver_expressions entry for that driver (every ? bound to the window cut-off)
// when one is configured, otherwise the portable expressionPrejavte lásku k open source
Tento balík je zadarmo pod licenciou MIT. Ak vám šetrí čas, jednorazový príspevok alebo členstvo na Patreone nám pomôže ho ďalej udržiavať, testovať a dokumentovať.
Ďalšie spôsoby podpory vrátane kryptomienOdoslaním daru súhlasíte s našimi podmienkami prijímania darov.
Chcete to zabudovať do svojho produktu?
Naše balíky integrujeme do zákazkových Laravel a AI riešení. Napíšte nám, na čom pracujete, a ozveme sa do 48 hodín.