2013-03-07 104 views
4

我有一個數據庫的地方,我存儲的經度和緯度。我想要查詢數據庫以查找特定緯度($latitude)和經度($longitude)的半徑($requestedDistance)內的所有地點。Symfony2,學說搜索和距離排序

下面的查詢工作並只返回這個半徑內的那些地方,但是我怎樣才能按距離排序,所以最接近的是第一個?在過去,使用原始SQL我已經在SELECT語句中完成了計算並將其設置爲'distance',然後使用HAVING distance < $requestedDistance ORDER BY distance,但是我不確定如何使用Doctrine Repository將計算添加到SELECT查詢中。

$d = $this->getDoctrine()->getRepository('XXXWebsiteBundle:Locations')->createQueryBuilder('l'); 
     $d 
      ->add('where','l.enabled = 1') 
      ->andWhere('(3959 * acos(cos(radians('.$latitude.')) 
       * cos(radians(l.latitude)) 
       * cos(radians(l.longitude) 
       - radians('.$longitude.')) 
       + sin(radians('.$latitude.')) 
       * sin(radians(l.latitude)))) < '.$requestedDistance); 

     $result= $d->getQuery(); 

UPDATE

我試過下面的查詢感謝@Lazy螞蟻:

$d = $this->getDoctrine()->getRepository('XXXWebsiteBundle:Locations')->createQueryBuilder('l'); 
    $d 
     ->select('l') 
     ->addSelect(
      '(3959 * acos(cos(radians(' . $latitude . '))' . 
       '* cos(radians(l.latitude))' . 
       '* cos(radians(l.longitude)' . 
       '- radians(' . $longitude . '))' . 
       '+ sin(radians(' . $latitude . '))' . 
       '* sin(radians(l.latitude)))) as distance' 
     ) 
     ->andWhere('l.enabled = :enabled') 
     ->setParameter('enabled', 1) 
     ->andWhere('distance < :distance') 
     ->setParameter('distance', $requestedDistance) 
     ->orderBy('distance', 'ASC'); 

但是,它返回以下錯誤:

`An exception occurred while executing 'SELECT COUNT(*) AS dctrn_count FROM 
(SELECT DISTINCT il0 FROM (SELECT l0_.id AS il0, l0_.name AS name2, l0_.address1 
AS address14, l0_.address2 AS address25, l0_.postcode AS postcode6, l0_.town AS 
town7, l0_.county AS county8, l0_.enabled AS enabled11, l0_.date_created AS 
date_created12, l0_.date_modified AS date_modified13, l0_.latitude AS 
latitude19, l0_.longitude AS longitude20, 3959 * ACOS(COS(RADIANS(53.51331889999999)) 
* COS(RADIANS(l0_.latitude)) * COS(RADIANS(l0_.longitude) - 
RADIANS(-2.935331099999985)) + SIN(RADIANS(53.51331889999999)) * 
SIN(RADIANS(l0_.latitude))) AS sclr21 FROM locations l0_ WHERE l0_.enabled = ? 
AND sclr21 < ? ORDER BY sclr21 ASC) dctrn_result) dctrn_table' with params 
{"1":1,"2":30}: 

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'sclr21' in 'where clause'` 
+0

看看https://github.com/djlambert/doctrine2-spatial – Axxiss 2013-03-07 09:47:25

+0

在這裏回答 - http://stackoverflow.com/questions/15272765/dql-returning-an-array-of-entities-instead-對象感謝@Ocramius – user1961082 2013-03-07 14:32:02

+0

這是Doctrine v1的內置功能,所以很煩人,他們刪除了它。 http://doctrine.readthedocs.io/en/latest/en/manual/behaviors.html#geographical – malhal 2016-10-01 15:40:48

回答

4
$d = $this->getDoctrine()->getRepository('XXXWebsiteBundle:Locations')->createQueryBuilder('l'); 
    $d 
     ->select('l') 
     ->addSelect(
      '(3959 * acos(cos(radians(' . $latitude . '))' . 
       '* cos(radians(l.latitude))' . 
       '* cos(radians(l.longitude)' . 
       '- radians(' . $longitude . '))' . 
       '+ sin(radians(' . $latitude . '))' . 
       '* sin(radians(l.latitude)))) as distance' 
     ) 
     ->andWhere('l.enabled = :enabled') 
     ->setParameter('enabled', 1) 
     ->having('distance < :distance') 
     ->setParameter('distance', $requestedDistance) 
     ->orderBy('distance', 'ASC'); 
+0

'執行'SELECT COUNT(*)AS時發生異常dctrn_count FROM(SELECT DISTINCT il0 FROM(SELECT *,3959 * ACOS(COS(RADIANS(53.51331889999999))* COS(RADIANS(l0_.latitude))* COS(RADIANS(l0_.longitude) - RADIANS(-2.935331099999985))+ SIN(RADIANS(53.51331889999999))* SIN(RADIANS(10。 ):)AS sclr21 FROM location l0_ WHERE l0_.enabled =?AND sclr21 <?ORDER BY sclr21 ASC)dctrn_result)dctrn_table'with params {「1」:1,「2」:30}: SQLSTATE [42S22]:未找到列:1054'where子句'中的未知列'sclr21' – user1961082 2013-03-07 10:54:59

+0

我已經從錯誤消息中刪除了一些字段,因爲它太長了評論。我還在查詢 – user1961082 2013-03-07 10:57:34

+0

中將' - >和Where('where','l.enabled =:enabled')'更改爲' - >和Where('l.enabled =:enabled')'此外,這會返回一個數組比對象? – user1961082 2013-03-07 13:05:27

-1

您正在使用沒有where()的andWhere()。

用where()替換andWhere()。

如果某些屬性映射到名爲「sclr21」的列上,請檢查您的實體定義,以便您還可以發現哪些屬性存在問題。