تماشای این درس نیاز به اشتراک حرفه‌ای دارد.

Filter Stores by Distance0:00

In the last lesson, we learned how to use geospatial functions to get the distance between two geographic points. In this lesson, we're going to update this page to limit the store results to only stores within a 10-kilometer distance. Let's start by going to the StoresController and adding a new withinDistanceTo scope call to our query. This method will take two arguments, the coordinates of our current user, and the distance we want to limit the results to. We'll pass in 10000 meters, which is 10 kilometers. Next, let's add this new scope to our Store model. public function scopeWithinDistanceTo, and that'll take an instance of the query builder, our coordinates, and the distance. So, to filter the results to only stores within a 10-kilometer distance, we'll simply calculate the distance again in the exact same way we did in the last lesson using the stDistance function. And then check if that calculated distance is less than or equal to the distance provided in our scope call.

Test Query Performance0:42

we'll simply calculate the distance again in the exact same way we did in the last lesson using the stDistance function. And then check if that calculated distance is less than or equal to the distance provided in our scope call. Then, we need to pass in our bindings, which include the longitude and latitude coordinates, as well as the distance. And now, if we hit refresh in the browser, we can see that this is working. We're only getting seven locations back. And if we look at our distance, that makes sense since they're all within 10 kilometers away. I don't know about you, but I think that's pretty cool. If we look at our combined query time in the Laravel debug bar, we can see that these queries are running in about 170 milliseconds, which honestly isn't bad if you consider that we're calculating the distance for all 4,500 stores on the fly. However, we can still speed this up a little.

Store Coordinates as Point1:21

which honestly isn't bad if you consider that we're calculating the distance for all 4,500 stores on the fly. However, we can still speed this up a little. Let's go to our stores database table migration. Right now, we're storing our coordinates in two separate longitude and latitude columns. However, each time we run the query, we need to then convert the longitude and latitude columns into a valid geometry object. And that operation takes time to do. What if we could pre-compute the geometry object instead? Well, as you might have guessed, we can. Let's remove the longitude and latitude columns from our migration and then add a new point column for the coordinates instead. The point method accepts a spatial reference identifier as a second argument.

Update Seeder for Location1:51

Let's remove the longitude and latitude columns from our migration and then add a new point column for the coordinates instead. The point method accepts a spatial reference identifier as a second argument. And just like in our query, we'll provide the 4326 identifier. Next, we need to make a quick change in our database seeder as well. Again, we'll remove the longitude and latitude columns and we'll add the new location column. And now we'll use a raw expression to run the same stsrid function call that we've been making in our queries to pre-compute the geometry object for our longitude and latitude values. Note, don't ever use a raw expression with the values inline like this if you're working with user provided data. That will expose you to SQL injection attacks. Instead, use binded parameters. Okay, now let's rerun our migrations in seeder.

Update Scopes and Retest2:33

Instead, use binded parameters. Okay, now let's rerun our migrations in seeder. Finally, let's go back to our Store model and update our scopes to use this new location column instead. And if we hit refresh in the browser, we can see that it still works and it's now running almost 100 milliseconds faster. Nice. In the next lesson, we'll update this page to order the locations by distance so that we can get the closest stores first.

Geometry ObjectsPoint Columns

دوست دارید گاهی خبرهای Laracasts را ایمیل کنیم؟