Доктрина 2 обнаружения дубликатов - PullRequest
4 голосов
/ 25 февраля 2012

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

ИЗОБРАЖЕНИЕ:

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

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

$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.

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

1 Ответ

3 голосов
/ 26 февраля 2012

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

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

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

...