2016-05-18 19 views
0

テーブルを結合しています。私は、結合に基づいて多次元のクエリ結果を得たいと思います。多次元配列の結果の結合

# AppBundle:ProductRepository 

$this->createQueryBuilder('pr') 
    ->select('pk.id', 'pk.name', 'pr.id', 'pr.label') 
    ->join('pr.package', 'pk') 
    ->getQuery()->getResult(); 

あなたがProductを見ることができるようにPackageここ

は私が取得していた結果の一種である(多くの1つ)にリンクされている。ここで

array(
    array('id' => '1', 'name' => 'package 1', 'id1' => 1, 'label' => 'product 1'), 
    array('id' => '1', 'name' => 'package 1', 'id1' => 2, 'label' => 'product 2'), 
    array('id' => '2', 'name' => 'package 2', 'id1' => 3, 'label' => 'product 3'), 
) 

は私がしたいです好きになる:

array(
    array(
     'id' => '1', 
     'name' => 'package 1', 
     'products' => array(
      array(
       'id' => 1, 
       'label' => 'product 1', 
      ), 
      array(
       'id' => 2, 
       'label' => 'product 2', 
      ), 
     ), 
    ), 
    array(
     'id' => '2', 
     'name' => 'package 2', 
     'products' => array(
      array(
       'id' => 3, 
       'label' => 'product 3', 
      ), 
     ), 
    ), 
) 

この種の多次元配列を水和する方法はありますかドクトリン2?

私は教義2と、いないと "ポストPROD" PHPは

答えて

3

ループあなたはarray hydratorpartial resultsの組み合わせを必要とするわけ。お試しください:

$this->createQueryBuilder('pr') 
    ->select('partial pk.{id, name}, partial pr.{id, .label}') 
    ->join('pr.package', 'pk') 
    ->getQuery() 
    ->getArrayResult() 
; 
+0

これは本当に面白いです。しかし、あなたの例は、 'packages'の代わりに' packages'の代わりに 'products'を' products'でリストアップしています。どうすれば元に戻せますか? –

+0

@PierredeLESPINAY正確なDB構造を持っていないので、実際の例を再現するのは難しいです。しかし、それは実際には本当に簡単です。必要なすべてのデータを選択して結合する* normal * dql文をどのように書くか考えてみてください。そこから、部分構文と配列のハイドレーションを使用して、必要な値だけに減らします。 – Yoshi

+1

別のことは、間違ったリポジトリにいるようだと思われるかもしれません。ルートエイリアス 'pr'を使ってクエリビルダーを作成しますが、' pk'で始まります。この方法でクエリービルダーを作成すると*暗黙的に* dqlの 'FROM'部分が設定されます。 – Yoshi

-2

私はあなたが記述したフォームにデータを結合するための小さなアルゴリズムを作成しました。

$source = array(
    array('id' => '1', 'name' => 'package 1', 'id1' => 1, 'label' => 'product 1'), 
    array('id' => '1', 'name' => 'package 1', 'id1' => 2, 'label' => 'product 2'), 
    array('id' => '2', 'name' => 'package 2', 'id1' => 3, 'label' => 'product 3'), 
); 

// Here is what I'd like to get: 

$target = array(
    array(
     'id' => '1', 
     'name' => 'package 1', 
     'products' => array(
      array(
       'id' => 1, 
       'label' => 'product 1', 
      ), 
      array(
       'id' => 2, 
       'label' => 'product 2', 
      ), 
     ), 
    ), 
    array(
     'id' => '2', 
     'name' => 'package 2', 
     'products' => array(
      array(
       'id' => 3, 
       'label' => 'product 3', 
      ), 
     ), 
    ), 
); 

// id => item 
$map = array(); 

foreach($source as $item) 
{ 
    // prepare product 
    $product = array(
     'id' => $item['id1'], 
     'label' => $item['label'], 
    ); 
    if (isset($map[$item['id']])) 
    { 
     // push data to existing item in $map 
     $map[$item['id']]['products'][] = $product; 
    } 
    else 
    { 
     // create new item in $map 
     $map[$item['id']] = array(
      'id' => $item['id'], 
      'name' => $item['name'], 
      'products' => array($product), 
     ); 
    } 
} 

function array_diff_assoc_recursive($array1, $array2) { 
    $difference=array(); 
    foreach($array1 as $key => $value) { 
     if(is_array($value)) { 
      if(!isset($array2[$key]) || !is_array($array2[$key])) { 
       $difference[$key] = $value; 
      } else { 
       $new_diff = array_diff_assoc_recursive($value, $array2[$key]); 
       if(!empty($new_diff)) 
        $difference[$key] = $new_diff; 
      } 
     } else if(!array_key_exists($key,$array2) || $array2[$key] !== $value) { 
      $difference[$key] = $value; 
     } 
    } 
    return $difference; 
} 

$new = array_values($map); 
var_export($new); 

echo "\ndiff: "; 
$diff = array_diff_assoc_recursive($target, $new); 
var_export($diff); 

機能array_diff_assoc_recursiveは、あなたが、部分的な結果とモデル1対多の関係を使用する必要がhttp://php.net/manual/en/function.array-diff-assoc.php

+0

R&Dをありがとうございますが、これは避けたかった "ポストプロード"のようなものです –

0

まずここGioshから借りています。例:お使いのコントローラで

$qb = $em->createQueryBuilder() 
     ->select('partial author.{id, name}, partial articles.{id, title, content}') 
     ->from('Module\Model\Author', 'author') 
     ->leftJoin('author.articles', 'articles'); 
$query = $qb->getQuery(); 
$results = $query->getArrayResult(); 

とOneToMany関係を使用することを忘れないでください。 http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/association-mapping.html#one-to-many-bidirectional

ので、モデルにAuthor.phpはこれを書く:

/** 
* @ORM\OneToMany(targetEntity="Articles", mappedBy="author") 
*/ 
private $articles; 

public function __construct() { 
    $this->articles = new ArrayCollection(); 
} 
関連する問題