简体   繁体   中英

Laravel get certain column from Query builder

I have a query as follows:

$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();  

I get Cardinality violation error which I know is because of nested query.
I need to get only id column from nested query but I can't.
I have tried using get(['id']) but it didn't work.
I even tried using array_map and returing sth like array_map(function ($venue){return $venue->id}, $venues); but I get the same error too.
How can I solve get only id column from query builder as an array. How can I pass

This is a just a guess, but your nested query function is not supposed to be executed by ->get() and you are not specifying the id column. Try this:

$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();

Edit: use query scope and calculated attributes

$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;
    })
    ;

app/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;
    }

}

app/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');
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM