2012-02-25 2 views
4

Я пытаюсь создать скрипт, который будет импортировать ключевые слова из изображений в базу данных. Ключевые слова в таблице ключевых слов должны быть уникальными, но многие изображения могут использовать одно и то же ключевое слово. Так что я написал эти две простые модели:Обнаружение дубликатов 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(); 
    } 
} 

СЛОВО:

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

Теперь, во время импорта, для каждого изображения я хочу добавить к БД только новые ключевые слова, и если изображение описывается с помощью существующего ключевого слова, я хочу добавить ссылку на этот существующий. Я хочу, чтобы достичь такой код:

$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 в части Bulk Inserts.

Возможно ли это? Может ли доктрина определить, существует ли определенное ключевое слово и автоматически добавлять к нему только refrence? Загрузка всех существующих ключевых слов из БД в каждом цикле и сравнение их с новым, загруженным с изображения, не является решением.

ответ

3

Это не поддерживается Doctrine2 на данный момент. Вам необходимо будет использовать ваш репозиторий через

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

Вы также можете использовать DQL, если хотите, но это самый быстрый способ. Так что да, у вас будет много накладных расходов. Что вы можете сделать, чтобы уменьшить это, создавая большие куски еще не сохраненных объектов, используйте условие IN(:fileNames) и, следовательно, уменьшите количество запросов по одному на пакетный кусок. В любом случае, чек по-прежнему зависит от вас.

+0

До сих пор я импортировал фотографии так, как вы описали. Я задал вопрос, потому что искал более оптимизированный способ. Но зная, что на данный момент я не могу сделать это лучше, это также важная информация. Благодарю. – qchar

Смежные вопросы