我已经完成了以下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);
但不幸的是,这不起作用,我想知道这是否可能,因为距离不是我的实体的真实属性,而是计算出来的?
这里的诀窍是什么?
答案 0 :(得分: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。
答案 1 :(得分: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神圣的道路而走向开发
答案 2 :(得分: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'];
});