原则 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();
}
}
现在,在导入过程中,对于每个图像,我只想添加到数据库中的新关键字,并且如果描述了图像对于现有关键字,我想添加对此现有关键字的引用。我想实现这样的代码:
$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://请阅读批量插入部分中的thedocs.org/docs/doctrine-orm/en/latest/reference/batch-processing.html。
这一切可能吗? Doctrine 可以确定某个关键字是否存在并自动仅添加引用吗?在每个循环中从数据库加载所有现有关键字并将它们与从图像加载的新关键字进行比较并不是解决方案。
I'm trying to create script, that will import keywords from images to database. Keywords in keyword table should be unique, but many images can share the same keyword. So I have wrote those two simple models:
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();
}
}
Now, during import, for every image i want to add to DB only new keywords, and if image is described with existing keyword i want add reference to this existing one. I want to achieve code like this:
$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();
}
Another thing to know is that I dont want to make a flush in every loop. I will be using something like described here: http://readthedocs.org/docs/doctrine-orm/en/latest/reference/batch-processing.html in Bulk Inserts part.
Is this all possible? Can Doctrine determine if certain keyword exists and automaticly add only refrence to it? Loading all existing keywords from DB in every loop and comparing them with new loaded from image isn't a solution.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
Doctrine2 目前不支持这一点。您必须通过以下方式使用您的存储库。
如果您愿意,也可以使用 DQL,但这是最快的方法。
所以是的,你将会有很多开销。
您可以采取的措施来减少它,即构建大量尚未持久化的实体,使用 IN(:fileNames) 条件,从而将查询数量减少到每批块一个。
无论如何,检查仍然取决于您。
This is not supported by Doctrine2 at the moment. You will have to use your repository through
You can also use DQL if you prefer, but this is the fastest way.
So yes, you will have a lot of overhead.
What you can do to reduce it is building up large chunks of not yet persisted entities, use a
IN(:fileNames)
condition and so reduce the number of queries to one per batch chunk.Anyway, the check is still up to you.