MatanYadaev / laravel-eloquent-spatial

Laravel Eloquent spatial package.
MIT License
332 stars 49 forks source link

Help using Spatial with Spatie QueryBuilder #106

Closed darkons closed 10 months ago

darkons commented 10 months ago

After the recent change that removes SpatialBuilder (#102), I am trying to use Spatie QueryBuilder to sort by distance.

$businesses = QueryBuilder::for(Business::class)
  ->allowedSorts([
      AllowedSort::custom('distance', new AddressDistanceSort()),
  ])
  ->paginate()
  ->withQueryString();
class AddressDistanceSort implements Sort
{
  public function __invoke(Builder $query, bool $descending, string $property)
  {
    $point = new Point(request()->latitude, request()->longitude, Srid::WGS84->value);

    $query->with(['address' => function ($query) use ($point, $descending) {
      $query->withDistance('location', $point);
    }]);

    // How to apply orderByDistance here???
  }
}

Obviously I'm not saying it's a bug in the Spatial package, but I think a lot of Laravel developers use Spatie QueryBuilder and I was wondering if anyone has managed to get this to work.

Could this package work together with Spatie QueryBuilder?

Thank you very much for your help and for this great package.

MatanYadaev commented 10 months ago

Hi @darkons. This package doesn't interact with Spatie QueryBuilder, AFAIK. From the snippet you attached it seems like you want to fetch Business and sort it by its relation column, which requires a join or a subquery. You can read about it here: https://stackoverflow.com/questions/38261546/order-by-relationship-column It's not very much related to this package.

Anyway, I think this code might be a good start for you. I didn't test it, so I'm not sure it will work.

$businesses = Business::query()
    ->orderByDesc(
        Address::select('ST_DISTANCE_SPHERE(location, "' . $point->toSqlExpression(DB::connection())  . '")')
            ->whereColumn('addresses.business_id', 'businesses.id')
            ->take(1);
    )
    ->get();