是否可以在laravel雄辩的查询中使用hasrsine?

时间:2016-01-09 19:40:14

标签: php laravel orm eloquent haversine

我创建了一个api,我获得了包含2个关系的商品:

  • 场地属于多种商品(manyToMany)
  • days belongsToMany offer(manyToMany)

然后,优惠会将关系同步并保存到它们中,并且在返回的json中,您可以看到天和场地的对象。

我现在要做的是使用hasrsine来获得提供场地lat / lng与hasrsine值的距离。我目前正在使用这个雄辩的查询来获得各自关系的优惠:

$(e).data('tot')

这完美无缺,我也没有问题。我现在想要使用hasrsine和场地的位置来获得优惠,但我很难看到这在eloquent查询中是如何工作的。

以下是每种关系的模型:

日期

$mytime = Carbon::now('Europe/London');
$time = $mytime->format('H:i');
$timeInt = $this->hourMinToInteger($time);
$today = $mytime->format('m/d/Y');
$day = strtolower($mytime->format('l'));
$tomorrow = strtolower(Carbon::now()->addDay(1)->format('l'));
$offersWithDays = Offer::with(['days','venues'])->get();

$response = [
    'now' => [],
    'later' => [],
    'tomorrow' => [],
    'featured' => []
];

// validOffers are all offers that fall within this stuff
foreach ($offersWithDays as $offerAll) {
    $relation = $offerAll->days()->get();

    $theDays = array();
    foreach ($relation as $theDay) {
      $theDayObj = $theDay->day;
      array_push($theDays,$theDayObj);
    }
    extract($theDays);

    if ($offerAll->is_featured) {
        $response['featured'][] = $offerAll;
    }
    if (in_array($day,$theDays) && $offerAll->offer_start_time < $time) {
        $response['now'][] = $offerAll;
    }
    if (in_array($day,$theDays) && $offerAll->offer_start_time > $time) {
        $response['later'][] = $offerAll;
    }
    if (in_array($tomorrow,$theDays)) {
        $response['tomorrow'][] = $offerAll;
    }
}

地点

use Illuminate\Database\Eloquent\Model;

class Day extends Model
{
    /**
     * Get the offer days for the offer.
     */

    protected $fillable = ['start_time','end_time'];

    public function offers()
    {

        return $this->belongsToMany('App\Offer');
    }
}

优惠

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Venue extends Model
{
    //
    use SoftDeletes;

    protected $table = 'venues';

    protected $dates = ['deleted_at'];

    protected $fillable = ['id','address','description','phone_number','website','name', 'headline','lat','lng','days'];

    public static $rules = array(
        'name' => ''
    );

    protected $casts = [
        'lat' => 'float(10,8)',
        'lng' => 'float(11,8)'
    ];

    public function offers()
    {
        return $this->belongsToMany('App\Offer','offer_venue');
    }

}

任何人都可以帮助我解决这个问题吗?

====编辑====

以下是我需要的具有Eloquent查询的json的示例输出:

enter image description here

查看日期和地点。我想在原始查询中找到这个,我已经在下面开始了,但是我在days表上直接查询,最好直接从商品表中查询并加入场地对象和日期对象,如附件:

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class Offer extends Model
{
    /**
     * The database table used by the model.
     *
     * @var string
     */

    use SoftDeletes;

    protected $table = 'offers';

    protected $dates = ['deleted_at'];
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $hidden  = ['map_location', 'regular', 'name', 'distance_to_offer'];
    protected $fillable = ['id','venue_id','type_id','day', 'venue_address','is_featured','repeater_days','image', 'venue_description', 'offer_headline','offer_subheader','offer_terms','venue_phone_number','venue_website', 'venue_name', 'venue_headline','venue_description','venue_latitude','venue_longitude','offer_when','offer_end_time','offer_start_time','offer_start_date','offer_end_date','featured_date','current_time','current_date'];
    public static $rules = array(
        'image' => 'image|mimes:jpeg,jpg,png,bmp,gif,svg'
    );
    protected $casts = [
        'is_featured' => 'boolean',
        'is_regular' => 'boolean',
        'offer_when' => 'array'
    ];
    /**
     * Get the offers for the offer.
    */
    public function days()
    {

        return $this->belongsToMany('App\Day','day_offer', 'offer_id', 'day_id');
    }

    public function types()
    {

        return $this->belongsToMany('App\Type', 'offer_type');
    }

    public function venues()
    {

        return $this->belongsToMany('App\Venue', 'offer_venue', 'offer_id', 'venue_id');
    }


}

1 个答案:

答案 0 :(得分:0)

我认为最终您希望能够根据用户坐标找到优惠?如果您将来获得10,000个优惠或场地 - 您不想逐个浏览它们并计算距离,然后显示最接近的匹配 - 这将是不可行的。

我会建议地理空间查询(由MySQL支持) - 例如。给我50个优惠(或场地)位于纬度X和经度Y的5公里范围内。

不幸的是,Eloquent不支持地理空间查询,因此您需要使用数据库外观进行原始查询,但性能会很好 - 您将立即获得结果。

在我看来,这是合理的方式。解析整套优惠/场地,实施距离计算,因为Trait是不合理的。