我的查询如下:
$locations = Location::select(DB::raw("* , 1000*distance AS distance"))
->whereIn("id", function ($q) use ($userLat, $distance, $userLng, $cityId)
{
$venues = $q->select('*')
->from('locations')
->where('city_id', $cityId)
->havingRaw("lat BETWEEN $userlat AND $userlat+10")
->havingRaw("lng BETWEEN $userLng AND $userlng+10")
->get();
})
->havingRaw('distance <' . $distance)
->orderBy('distance')
->take($limit)
->get();
我得到Cardinality violation
错误,我知道这是因为嵌套查询
我需要从嵌套查询中获取id
列,但我不能
我尝试过使用get(['id'])
,但它没有用
我甚至尝试使用array_map
并像array_map(function ($venue){return $venue->id}, $venues);
那样退缩,但我也得到了同样的错误
我如何解决从查询构建器中仅获取id
列作为数组。
我怎么能通过
答案 0 :(得分:0)
这只是一个猜测,但您的嵌套查询函数不应由->get()
执行,并且您没有指定id
列。试试这个:
$locations = Location::select(DB::raw("* , 1000*distance AS distance"))
->whereIn("id", function ($q) use ($userLat, $distance, $userLng, $cityId)
{
$venues = $q->select('id')
->from('locations')
->where('city_id', $cityId)
->havingRaw("lat BETWEEN $userlat AND $userlat+10")
->havingRaw("lng BETWEEN $userLng AND $userlng+10")
;
})
->havingRaw('distance <' . $distance)
->orderBy('distance')
->take($limit)
->get();
编辑:使用查询范围和计算属性
$lat = ''; // latitude
$lng = ''; // longitude
$distance = 5; // distance amount
$radius = compact('lat', 'lng', 'distance');
$targets = Location::withinRadius($radius)
->with('city')
->get()
->map(function ($value, $key) use ($lat, $lng) {
return $value->target = [$lat, $lng];
})
->filter(function ($value, $key) use ($distance) {
return $value->distance < $distance;
})
;
应用程序/ Location.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Location extends Model
{
// Add the attributes for inclusion in toArray() and toJson()
protected $appends = ['target', 'distance'];
// Hold the target Location
protected $_target = null;
// ... other model code
/**
* Return the query with radius limits
*/
public function scopeWithinRadius($q, $radius)
{
$target_lat = $radius['lat'];
$target_lng = $radius['lng'];
$distance = $radius['distance'];
$target_lat_range = [$target_lat + $this->adjustLat($distance * -1), $target_lat + $this->adjustLat($distance)];
$target_lng_range = [$target_lng + $this->adjustLng($distance * -1), $target_lng + $this->adjustLng($distance)];
return $q->havingRaw("lat BETWEEN " . $target_lat_range[0] ." AND ".$target_lat_range[1])
->havingRaw("lng BETWEEN " . $target_lng_range[0] ." AND ".$target_lng_range[1])
;
}
/**
* Return the amount to adjust latitude by for the given distance
*/
private function adjustLat($distance)
{
// return latitude adjustment amount
}
/**
* Return the amount to adjust longitude by for the given distance
*/
private function adjustLng($distance)
{
// return longitude adjustment amount
}
/**
* Get the Target coordinates
*/
public function getTargetAttribute()
{
return $this->_target;
}
/**
* Get the Target latitude
*/
public function getTargetLatAttribute()
{
return $this->_target[0];
}
/**
* Get the Target longitude
*/
public function getTargetLngAttribute()
{
return $this->_target[1];
}
/**
* Set the Target of the Location
*/
public function setTargetAttribute($value)
{
// check if value is a Location
if ($value instanceof Location) {
$value = [$value->lat, $value->lng];
}
$this->_target = $value;
}
/**
* Determine the Distance from target
*/
public function getDistanceAttribute()
{
$lat1 = $this->lat;
$lng1 = $this->lng;
$lat2 = $this->target_lat;
$lng2 = $this->target_lng;
// calculate the distance between Location and points
// ... $distance = ...
return $distance;
}
}
应用程序/ City.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class City extends Model
{
// ... other model code
/**
* Get the Location of the City
*/
public function location()
{
return $this->hasMany('App\Location');
}
}