将包含doctrine查询的虚拟字段添加到symfony实体

时间:2017-06-27 21:04:25

标签: php symfony doctrine-orm doctrine

我的symfony项目中有一个实体,如下所示:

<?php

namespace AppBundle\Entity;
...
/**
 * @ORM\Entity(repositoryClass="AppBundle\Repository\RestaurantRepository")
 */
class Restaurant {

    use TimestampableTrait;

    /**
     * @ORM\Column(type="guid")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="UUID")
     */
    protected $id;
    /**
     * @ORM\Column(type="float", nullable=true)
     */
    protected $latitude;
    /**
     * @ORM\Column(type="float", nullable=true)
     */
    protected $longitude;
}

我现在已经在我的EntityRepository中编写了一个学说查询来选择餐馆以及该位置所订购位置附近的距离。问题是,获取一个结果如下所示的数组:

[0] =>
  (
    [0] => distance1
    [1] => restaurant1
  )
[1] =>
  (
    [0] => distance2
    [1] => restaurant2
  )

我想,距离是&#34;虚拟&#34;餐厅的字段,所以结果数组应如下所示:

[0] =>
  (
    [0] => restaurant1
  )
[1] =>
  (
    [0] => restaurant2
  )

我的学说查询:

$r = $this->createQueryBuilder('l');
        $r
            ->select('l')
            ->addSelect(
                '( 3959 * acos(cos(radians(' . $cord['latitude'] . '))' .
                '* cos( radians( l.latitude ) )' .
                '* cos( radians( l.longitude )' .
                '- radians(' . $cord['longitude'] . ') )' .
                '+ sin( radians(' . $cord['latitude'] . ') )' .
                '* sin( radians( l.latitude ) ) ) ) as distance'
            );
        $r->orderBy('distance', 'ASC');
        return $r->getQuery()->getResult();

感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

我认为只使用查询是不可能的。我有一个类似的任务,需要循环结果来设置虚拟属性:

$r = $this->createQueryBuilder('l');
$r
    ->select('l')
    ->addSelect(
        '( 3959 * acos(cos(radians(' . $cord['latitude'] . '))' .
        '* cos( radians( l.latitude ) )' .
        '* cos( radians( l.longitude )' .
        '- radians(' . $cord['longitude'] . ') )' .
        '+ sin( radians(' . $cord['latitude'] . ') )' .
        '* sin( radians( l.latitude ) ) ) ) as distance'
    );
$r->orderBy('distance', 'ASC');

$results = $r->getQuery()->getResult();

//  need to loop over results to add the distance to the object itself
$restaurants = array();

foreach ( $results as $result ) {
    $restaurant = $result[1];
    $restaurant->setDistance( $result[0] );
    $restaurants[] = $restaurant;
}

return $restaurants;

可以说,如果不应该将这种类型的逻辑更好地放入添加另一个业务逻辑层的服务类中。那时对我来说这是一个有效的解决方案。

我在搜索中使用了距离字段,这就是我在查询中需要它的原因。如果只需要实体中的距离而不在查询中使用,则可以轻松地将其移出存储库并创建Event Listener来设置虚拟属性。