如何按位置距离对Laravel集合进行排序?

时间:2018-12-14 13:21:01

标签: php sql laravel sorting distance

使用以下代码,我尝试执行以下操作:

  • 从我的数据库中获取所有Advertenties
  • 计算其相关用户到客户位置的距离
  • 排序
  • 返回分页结果。

现在,它不按distance排序,我也不知道为什么。在我看来,Laravel的orderBy方法应按distance对其进行排序。

我也尝试过usort,但这给我一个错误,指出它不能带物体。

返回的数组按user_id排序。

    class AdvertentiesSearchController extends Controller
    {
    public function homeSearch(Request $request) {

    $queryWhereArr = [];
    $queryWhereArr[] = ['advertenties.title','like',"%$request->search_text%"];
    $queryWhereArr[] = ['users.name','like',"%$request->search_filter_user%"];

    if ($request->search_select != 1) {
        //doesn't include this where condition if ALL category is selected
        $queryWhereArr[] = ['subcategories.category_id','=',$request->search_select];
    }

    $user = User::find(auth()->id());
    if (!$user || !$user->latitude) {
        $user = (object) [
            "latitude" => $request->user_lat,
            "longitude" => $request->user_lng,
        ];
    }

    if ($request->search_distance > 0) {
        $queryWhereArr[] = ['users.latitude','>',$user->latitude-(1/111.1111)*$request->search_distance];
        $queryWhereArr[] = ['users.latitude','<',$user->latitude+(1/111.1111)*$request->search_distance];
        $longitudeMargin = (1/111.1111)/cos(abs($user->latitude)/57.295);
        $queryWhereArr[] = ['users.longitude','>',$user->longitude-$longitudeMargin*$request->search_distance];
        $queryWhereArr[] = ['users.longitude','<',$user->longitude+$longitudeMargin*$request->search_distance];
    }
    // return $queryWhereArr;

    $expl = explode(".",$request->search_sort_by);
    $sortBy = $expl[0].".".$expl[1];

    if ($expl[1] == "price" || $expl[1] == "created_at") {
        if ($expl[2] == "desc") {
            $advertenties = Advertentie::
                where('price', '<', 1e9)
            ->join('subcategories', 'advertenties.subcategory_id', '=', 'subcategories.id')
            ->join('users', 'advertenties.user_id', '=', 'users.id')
            ->select('advertenties.*', 'subcategories.category_id', 'users.city', 'users.latitude', 'users.longitude')
            ->where($queryWhereArr)
            ->orderByDesc($sortBy)
            ->get();
        } else {
            $advertenties = Advertentie::
                where('price', '<', 1e9)
            ->join('subcategories', 'advertenties.subcategory_id', '=', 'subcategories.id')
            ->join('users', 'advertenties.user_id', '=', 'users.id')
            ->select('advertenties.*', 'subcategories.category_id', 'users.city', 'users.latitude', 'users.longitude')
            ->where($queryWhereArr)
            ->orderBy($sortBy)
            ->get();
        }
    } else {
        $advertenties = Advertentie::
            where('price', '<', 1e9)
        ->join('subcategories', 'advertenties.subcategory_id', '=', 'subcategories.id')
        ->join('users', 'advertenties.user_id', '=', 'users.id')
        ->select('advertenties.*', 'subcategories.category_id', 'users.city', 'users.latitude', 'users.longitude')
        ->where($queryWhereArr)
        ->get();
    }

    //calculate distances and filter out far away advertenties (if necessary)
    $tempArr = [];
    $debug = [];
    if ($request->search_distance == 0) {
        foreach ($advertenties as $advertentie) {
            $advertentie->distance = null;
        }
        $tempArr = $advertenties;
    } else {
        foreach ($advertenties as $advertentie) {

            if (!$advertentie->latitude) {continue;}

            $advertentie->distance = 
             (($advertentie ->latitude  - $user->latitude)                                                                          **2)
            +((($advertentie->longitude - $user->longitude)/cos($advertentie->latitude/57.295)) **2)
            **.5 / .009;
            if ($advertentie->distance < $request->search_distance) {
                $tempArr[] = $advertentie;

            }
        }
    }

    //sort by distance
    if ($expl[1] == "distance") {
        if ($expl[2] == "desc") {
            $advertenties->sortByDesc("distance");
        } else {
            $advertenties->sortBy("distance");
        }
    }

    $offset = 6;
    $count = 0;
    $data = [];
    while ($count++ < $offset) {
        $arrPos = $count+$offset*($request->search_paginate_nr-1);
        if (isset($tempArr[$arrPos])) {
            $data[] = $tempArr[$arrPos];
        }
    }

    return $data;

}

// html端的javascript

function searchQuery(){
    if (resultLength < 2){
        let pagNr = $('#paginate-number');
        pagNr.val(1);
    }
    jQuery.ajax({
        url: "/advertenties.search.index",
        method: 'post',
        data: {
            search_text: jQuery('#home-search-text').val(),
            search_select: jQuery('#home-search-select').val(),
            search_paginate_nr: jQuery('#paginate-number').val(),
            search_distance: jQuery('#home-search-distance').val()||0,
            user_lat: userLat||6.566,
            user_lng: userLng||53.212, 
            search_sort_by: jQuery('#select-sort-by').val(),
            search_filter_user: jQuery('#filter-user').val(),
        },
        success: function(result){
            console.log(result);
            resultLength = result.length;
            if (!resultLength) {
                let pagNr = $('#paginate-number');
                pagNr.val(1);
            }
            refreshResults(result);
        },
        error: function(jqxhr, status, exception) {
            console.log(jqxhr);
            console.log('Exception:', exception);
            console.log(status);
        }
    });
};

0 个答案:

没有答案