2017-06-27 3 views
1

symfonyのエンティティに教義のクエリを使用して仮想フィールドを追加します。場所によって注文された場所。問題は、このようになります。結果と配列を取得することを、次のとおりです。次のようになります私は私のsymfonyプロジェクト内のエンティティを持っている

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

私は距離では、レストランの「仮想」フィールドがあることを、したいので、結果の配列は次のようになります。

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

ありがとう!

+0

'$ cord'とは何ですか?どこから来たのですか?一部のデータベースはデータベースレベルの仮想フィールドをサポートしていますが、すべての計算は同じ行の他の列から行う必要があります。 – Kaspars

答えて

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; 

ロジックのこのタイプは、より良い別のビジネスロジック層を追加するサービスクラスに入れすべきでない場合は、1つは主張することができます。当時の私にとっては、それは有効な解決策でした。

検索で距離フィールドを使用しました。その理由は、クエリで必要な理由です。 でエンティティ内の距離が必要なだけで、クエリで使用しない場合は、をリポジトリから簡単に移動して、Event Listenerを作成して仮想プロパティを設定できます。

+2

いくつかの他の解決策 - 実際にオブジェクトに「仮想」フィールドが必要な場合は、カスタムハイドレーターを使用することもできます。別の方法 - 並べ替えをしたいだけで実際の距離の列を返す必要がない場合は、 'HIDDEN distance'を実行することができ、Doctrineは結果に結果を返しません。次に、あなたのエンティティの 'getDistance()'メソッドであなたのロジックを複製することができます。 –

関連する問題