如何进行 Doctrine2 计算字段排序

问题描述 投票:0回答:3

我已经得到了以下的doctrine2查询,它运行良好,它检索某个地理半径内的所有“标记”。

    $qb->select('marker')
        ->from('SndSpecialistLocator\Entity\Marker', 'marker')
        ->where('DISTANCE(marker.location, POINT_STR(:point)) < :distance')
        ->setParameter('point', $point)
        ->setParameter('distance', $radius);

现在我想按距离对它们进行排序。

    $qb->select('marker (DISTANCE(marker.location, POINT_STR(:point))) AS distance')
        ->from('SndSpecialistLocator\Entity\Marker', 'marker')
        ->where('DISTANCE(marker.location, POINT_STR(:point)) < :distance')
        ->setParameter('point', $point)
        ->orderBy('distance', 'DESC')
        ->setParameter('distance', $radius);

但不幸的是,这不起作用,我想知道这是否可能,因为距离不是我实体的真实属性,而是计算出来的?

这里有什么技巧?

php doctrine-orm
3个回答
2
投票

或者,尝试在 select() 调用中使用 HIDDEN :

$qb->select('m as marker, (DISTANCE(m.location, POINT_STR(:point))) as HIDDEN distance')
// note HIDDEN added here --->------->------->------->------->------->---^
    ->from('SndSpecialistLocator\Entity\Marker', 'm')
    ->where('DISTANCE(m.location, POINT_STR(:point)) < :distance')
    ->setParameter('point', $point)
    ->orderBy('distance', 'ASC')
    ->setParameter('distance', $radius)
    ->setMaxResults(5);

$query = $qb->getQuery();
$result = $query->execute();

将 HIDDEN 添加到 SELECT 子句会在结果中隐藏它,但允许在 orderby 子句中使用它。然后,您的 $result 应该包含您想要的对象,而无需执行额外的 array_walk。


0
投票

不幸的是,无法通过别名排序。 您可以做的*是在 orderBy 语句中手动重复该函数:

$qb->select('marker (DISTANCE(marker.location, POINT_STR(:point))) AS distance')
    ->from('SndSpecialistLocator\Entity\Marker', 'marker')
    ->where('DISTANCE(marker.location, POINT_STR(:point)) < :distance')
    ->setParameter('point', $point)
    ->orderBy('DISTANCE(marker.location, POINT_STR(:point))', 'DESC')
    ->setParameter('distance', $radius);

*我们可能都会因为离开 DRY 的神圣道路而最终陷入开发地狱


0
投票

找到解决方案。

   $qb->select('m as marker, (DISTANCE(m.location, POINT_STR(:point))) as distance')
        ->from('SndSpecialistLocator\Entity\Marker', 'm')
        ->where('DISTANCE(m.location, POINT_STR(:point)) < :distance')
        ->setParameter('point', $point)
        ->orderBy('distance', 'ASC')
        ->setParameter('distance', $radius)
        ->setMaxResults(5);

    $query = $qb->getQuery();
    $result = $query->execute();

    /**
     * Convert the resulting associative array into one containing only the entity objects
     *
     * array (size=5)
     *   0 =>
     *     array (size=2)
     *       'marker' =>
     *         object(SndSpecialistLocator\Entity\Marker)[647]
     *           protected 'id' => int 43
     *           protected 'title' => string 'c5d07acdd47efbe38a6d0bf4ec64f333' (length=32)
     *           private 'location' =>
     *             object(SndSpecialistLocator\Orm\Point)[636]
     *                private 'lat' => float 52.2897
     *                private 'lng' => float 4.84268
     *       'distance' => string '0.0760756823433058' (length=18)
     *   1 => ...
     *
     * array (size=5)
     *   0 =>
     *     object(SndSpecialistLocator\Entity\Marker)[647]
     *       protected 'id' => int 43
     *       protected 'title' => string 'c5d07acdd47efbe38a6d0bf4ec64f333' (length=32)
     *       private 'location' =>
     *         object(SndSpecialistLocator\Orm\Point)[636]
     *           private 'lat' => float 52.2897
     *           private 'lng' => float 4.84268
     *   1 => ...
     *
     */
    array_walk($result, function (&$item, $key)
    {
        $item = $item['marker'];
    });
© www.soinside.com 2019 - 2024. All rights reserved.