2016-07-05 141 views
0

得到一定的專欄中,我有一個查詢,如下所示:Laravel從查詢生成器

$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

刪除'Location :: select'並僅嘗試使用數據庫門面。 – xhulio

回答

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'); 
    } 
} 
+0

我在嵌套查詢中使用「lat」和「lng」,所以只選擇「id」將不起作用 – Mehrdad

+0

在傳統SQL子查詢中,除非引用'lat'和'lng'列你不需要選擇它們。你在這裏所做的沒有其他建議。您從滿足特定條件的記錄中選擇'id',這不需要'lat'和'lng'。 – Qevo

+0

距離是從哪裏來的? – Qevo