सबसे पहले, आइए देखें कि मूल क्वेरी बिल्डर के साथ इसे कैसे करें। फिर, हम चर्चा करेंगे कि इस क्वेरी को एलोक्वेंट मॉडल के साथ कैसे निष्पादित किया जाए:
function paginateDishesFromPoint(Point $point, $pageSize)
{
$distanceField = "ST_Distance_Sphere(locations.coordinates, "
. "ST_GeomFromText('{$point->toWKT()}') AS distance";
return DB::table('dishes')
->select('dishes.*', DB::raw($distanceField))
->join('dish_locations', 'dish_locations.dish_id', '=', 'dishes.id')
->join('locations', 'locations.id', '=', 'dish_locations.location_id')
->orderBy('distance')
->paginate($pageSize);
}
ST_Distance_Sphere()
फ़ंक्शन उस दूरी की गणना करता है जिसके द्वारा हम परिणाम सॉर्ट कर सकते हैं। लारवेल का paginate()
विधि page
. का उपयोग करके हमारे लिए स्वचालित पृष्ठांकन करती है अनुरोध URL के माध्यम से पारित पैरामीटर। पेजिनेशन डॉक्स
पढ़ें अधिक जानकारी के लिए। ऊपर दिए गए फ़ंक्शन के साथ, हम निम्नानुसार एक पेजिनेटेड परिणाम सेट प्राप्त कर सकते हैं:
$point = new Point($latitude, $longitude);
$sortedDishes = paginateDishesFromPoint($point, 15);
...जहां Point
यह Grimzy\LaravelMysqlSpatial\Types\Point
है पैकेज
से क्लास हम उपयोग कर रहे हैं, और 15
प्रति पृष्ठ परिणामों की संख्या है।
अब, आइए इसे सुवक्ता मॉडल के साथ करने का प्रयास करें। हम स्थानीय क्वेरी स्कोप का उपयोग करेंगे आदेश देने वाले क्वेरी के हिस्से को बनाने के लिए आवश्यक तर्क को समाहित करने के लिए:
class Dish extends Model
{
...
public function locations()
{
return $this->belongsToMany(App\Location::class);
}
public function scopeOrderByDistanceFrom($query, Point $point)
{
$relation = $this->locations();
$locationsTable = $relation->getRelated()->getTable();
$distanceField = "ST_Distance_Sphere($locationsTable.coordinates, "
. "ST_GeomFromText('{$point->toWKT()}') AS distance";
return $query
->select($this->getTable() . '.*', DB::raw($distanceField))
->join(
$relation->getTable(),
$relation->getQualifiedForeignKeyName(),
'=',
$relation->getQualifiedParentKeyName()
)
->join(
$locationsTable,
$relation->getRelated()->getQualifiedKeyName(),
'=',
$relation->getQualifiedRelatedKeyName()
)
->orderBy('distance');
}
}
यह कार्यान्वयन क्वेरी में तालिका और फ़ील्ड नाम जोड़ने के लिए मॉडल पर मेटाडेटा का उपयोग करता है, इसलिए यदि वे बदलते हैं तो हमें इस पद्धति को अपडेट करने की आवश्यकता नहीं है। अब हम मॉडल का उपयोग करके ऑर्डर किया गया सेट प्राप्त कर सकते हैं:
$point = new Point($latitude, $longitude);
$sortedDishes = Dish::orderByDistanceFrom($point)->paginate($pageSize);
$sortedDishes
लारवेल के LengthAwarePaginator
. का एक उदाहरण है जो एक Collection
. को लपेटता है मॉडलों की। यदि हम परिणामों को एक दृश्य में पास करते हैं, तो उन्हें ब्लेड टेम्पलेट में प्रदर्शित करने का तरीका यहां बताया गया है:
<ul>
@foreach($sortedDishes as $dish)
<li>{{ $dish->name }} is {{ $dish->distance }} meters away.</li>
@endforeach
</ul>
<a href="{{ $sortedDishes->nextPageUrl() }}">Load more...</a>
जैसा कि ऊपर दिखाया गया है, पेजिनेटर सुविधा विधियां प्रदान करता है जिसका उपयोग हम आसानी से पृष्ठांकित परिणामों के बीच स्थानांतरित करने के लिए कर सकते हैं।
वैकल्पिक रूप से, हम परिणाम लोड करने के लिए AJAX अनुरोधों का उपयोग कर सकते हैं। बस वर्तमान पृष्ठ + 1 . पास करना सुनिश्चित करें page
. में अनुरोध डेटा का पैरामीटर।