2012-02-25 15 views
4

私はスクリプトからイメージをデータベースにインポートするスクリプトを作成しようとしています。キーワード表のキーワードは一意である必要がありますが、多くの画像で同じキーワードを共有できます。だから私は、これらの2つの単純なモデルを書いている:Doctrine 2重複検出

IMAGE:

class Image 
{ 
    /** 
    * @ORM\Id 
    * @ORM\Column(type="integer") 
    * @ORM\GeneratedValue 
    */ 
    private $id; 

    /** @ORM\Column(unique=true, nullable=false) */ 
    private $filename; 

    /** 
    * @ORM\ManyToMany(targetEntity="Keyword", inversedBy="images", cascade={"persist"}) 
    * @ORM\JoinTable(name="image_keyword_binder") 
    */ 
    private $keywords; 

    public function __construct() 
    { 
     $this->keywords = new \Doctrine\Common\Collections\ArrayCollection(); 
    } 
} 

KEYWORD:

class Keyword 
{ 
    /** 
    * @ORM\Id 
    * @ORM\Column(type="integer") 
    * @ORM\GeneratedValue 
    */ 
    private $id; 

    /** 
    * @ORM\Column(type="string", nullable=false, unique=true) 
    */ 
    private $text; 

    /** 
    * @ORM\ManyToMany(targetEntity="Image", mappedBy="keywords") 
    */ 
    private $images; 

    public function __construct() 
    { 
     $this->images = new \Doctrine\Common\Collections\ArrayCollection(); 
    } 
} 

さて、インポート時に、すべての画像のために、私はDBに追加するだけ新しいキーワード、イメージが既存のキーワードで記述されている場合は、この既存のものへの参照を追加します。私はこのようなコードを達成したい:

$images[] = array('filename'=>'image1.jpg', 'keywords'=>array('blue', 'green', 'yellow')); 
$images[] = array('filename'=>'image2.jpg', 'keywords'=>array('pink', 'green', 'yellow')); 
$images[] = array('filename'=>'image2.jpg', 'keywords'=>array('black', 'green', 'red')); 

foreach($images as $img) 
{ 
$image = new \FL\Entity\Image(); 
$image->setFilename($image['filename']); 
$image->setKeywords($image['keywords']); 

// em is Entity Manager Instance 
$em->persist($image); 
$em->flush(); 
} 

知っているもう一つのことは、私はすべてのループでフラッシュを作りたいいけないということです。私はここで説明されているような何かを使用します:http://readthedocs.org/docs/doctrine-orm/en/latest/reference/batch-processing.htmlバルクインサートの部分です。

これはすべて可能ですか? Doctrineは特定のキーワードが存在するかどうかを判断し、自動的にそのキーワードのみを追加できますか?すべての既存のキーワードをすべてのループ内のDBからロードし、新しいロード済みのイメージと比較することは解決策ではありません。

答えて

3

これは現時点でDoctrine2ではサポートされていません。リポジトリを使用する必要があります。

$image = $repository->findOneBy(array('filename' => $checkedFileName)); 
if ($image) { 
    // use reference 
} else { 
    // create new entity instance 
} 

好きな場合は、DQLも使用できますが、これが最速の方法です。 そうです、オーバーヘッドが大きくなります。 これを減らすためにできることは、まだ永続化されていないエンティティの大きなチャンクを構築することです。IN(:fileNames)条件を使用して、バッチチャンクごとに1つのクエリ数を減らします。 とにかく、チェックはあなた次第です。

+0

これまで説明した方法で写真をインポートしていました。私はより最適化された方法を探していたので、質問をしました。しかし、知っている、私はそれを行うことができない瞬間にも重要な情報です。ありがとう。 – qchar