2012-08-14 91 views
5

我發現Doctrine數組類型正在使用serialize/unserialize並將數據存儲在像text,integer這樣的「簡單」字段中。Doctrine和Postgres數組

但我有一個postgres數據庫項目的數組(主要是文本)的項目。我想在Doctrine中使用該數據庫。有辦法處理嗎?

感謝

編輯:

PS:我現在知道,SQL數組可以是一個很好的做法,感謝Craig鈴聲。

也許我可以創建一個自定義類型。有人已經做到了嗎?

編輯2:

問題解決了一半:

<?php 
namespace mysite\MyBundle\Types; 

use Doctrine\DBAL\Types\Type; 
use Doctrine\DBAL\Platforms\AbstractPlatform; 

/** 
    * My custom postgres text array datatype. 
*/ 
class TEXTARRAY extends Type 
{ 
    const TEXTARRAY = 'textarray'; // modify to match your type name 

    public function getSqlDeclaration(array $fieldDeclaration, AbstractPlatform $platform) 
    { 
     return $platform->getDoctrineTypeMapping('TEXTARRAY'); 
    } 

    public function convertToPHPValue($value, AbstractPlatform $platform) 
    { 
    // This is executed when the value is read from the database. Make your conversions here, optionally using the $platform. 
     return explode('","', trim($value, '{""}')); 
    } 

    public function convertToDatabaseValue($value, AbstractPlatform $platform) 
    { 
    // This is executed when the value is written to the database. Make your conversions here, optionally using the $platform. 

     settype($value, 'array'); // can be called with a scalar or array 
     $result = array(); 
     foreach ($set as $t) { 
      if (is_array($t)) { 
       $result[] = to_pg_array($t); 
      } else { 
       $t = str_replace('"', '\\"', $t); // escape double quote 
       if (! is_numeric($t)) // quote only non-numeric values 
        $t = '"' . $t . '"'; 
       $result[] = $t; 
      } 
     } 
     return '{' . implode(",", $result) . '}'; // format  

    } 

    public function getName() 
    { 
     return self::TEXTARRAY; // modify to match your constant name 
    } 
} 

和控制器

<?php 

namespace mysite\MyBundle; 

use Symfony\Component\HttpKernel\Bundle\Bundle; 
use Doctrine\ORM\EntityManager; 
use Doctrine\DBAL\Types\Type; 

class mysiteMyBundle extends Bundle 
{ 
    public function boot() { 
     Type::addType('textarray', 'mysite\MyBundle\Types\TextArray'); 
     $em = $this->container->get('doctrine.orm.default_entity_manager'); 
     $conn = $em->getConnection(); 
     $conn->getDatabasePlatform()->registerDoctrineTypeMapping('TEXTARRAY', 'textarray'); 
    } 
} 

我知道想這些陣列內搜索與像 'myword'=任何疑問(myarrayfield)......有人有線索嗎?

有人在#doctrine2渠道告訴我建立一個定製DQL功能,所以在這裏它是:

<?php 
use Doctrine\ORM\Query\Lexer; 
use Doctrine\ORM\Query\AST\Functions\FunctionNode; 

class ANY extends FunctionNode { 

    public $field; 


    public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker) { 
     return 'ANY(' . 
      $this->field->dispatch($sqlWalker) . ')'; 
    } 

    public function parse(\Doctrine\ORM\Query\Parser $parser) { 
     $parser->match(Lexer::T_IDENTIFIER); 
     $parser->match(Lexer::T_OPEN_PARENTHESIS); 
     $this->field = $parser->StringPrimary(); 
     $parser->match(Lexer::T_CLOSE_PARENTHESIS); 
    } 
} 

但是,我建我的查詢與查詢生成器,包含陣列之類的東西

$arr[] = $qb->expr()->like($alias.".".$field, $qb->expr()->literal('%'.trim($val).'%')); 

而且隨着

if(count($arr) > 0) $qb->Where(new Expr\Orx($arr)); 
else unset($arr); 

那麼,如何用我的功能加入他們? :\

+2

SQL數組實際上是一個非常方便的反規範化,在明智而謹慎地使用時可以大幅提升性能。他們不應該沒有很好的理由,不便攜式等等。 – 2012-08-14 11:44:54

回答

4

的QueryBuilder的,你可以只寫他們使用自定義函數中:

$qb->where("ANY(a.b)"); 

一些進一步的信息:

  1. 您可以添加自定義類型的「主義」配置節你的Symfony應用程序。
  2. 這同樣適用於自定義DQL函數。

有關Symfony 2.1中的語法,請參閱CLI上的「config:dump-reference DoctrineBundle」命令,否則請在symfony.com網站上查看。