我正在使用Symfony2和Doctrine2以及MySQL。
我创建了2个实体:
我正在尝试从标签ID列表中获取文章的OR和AND。
一个例子可能更好:
我会从我的标签ID [2,3]的列表中,做一个AND和OR请求,以获得一些文章:
我成功地在PHP代码中使用循环对多个请求进行OR查询,这实际上根本没有优化。而且我害怕对AND的请求数进行组合爆炸。 我知道有一种正确的方法可以在MySQL中使用JOIN来实现它,我猜是Doctrine2语言,在一个请求中,但是我阅读和尝试的文档越多,我就会发现它不是我的计算级别。
如果有人能在这一点上帮助我,我会很感激。
编辑:这是我目前的解决方案,未经优化:
class TagRepository extends EntityRepository
{
public function getItemsFromIds($ids)
{
$qb = $this->createQueryBuilder('a');
$qb->where('a.id IN (:ids)')
->setParameter('ids', $ids);
return $qb->getQuery()->getResult();
}
}
然后在我的DefaultController.php中,处理这些东西的函数:
$finalarticles = array();
$tagsrepository = $this->getDoctrine()
->getEntityManager()
->getRepository('ElephantTagsBundle:Tag');
$tags = $tagsrepository->getItemsFromIds($tagids);
$nbtags = count($tags);
foreach ($tags as $tag) {
$articles = $tag->getArticles();
foreach ($articles as $article) {
$articlestags = $article->getTags();
$tmpnbtags = 0;
foreach ($articlestags as $articlestag) {
if (in_array($articlestag->getId(), $tagids))
$tmpnbtags += 1;
}
if ($tmpnbtags == $nbtags)
$finalarticles[$article->getId()] = $article;
}
}
正如你所看到的,这个方法包括3个for循环(我猜是“array_in”中的一个),其中包括很多MySQL调用。我确信在存储库中有一个正确的方法!
答案 0 :(得分:0)
请从resources / config文件夹中提供您的实体定义。您正在寻找的是双向关联映射。看一下文档:
在您的文章中:
<many-to-many target-entity="Tag" inversed-by="articles" field="articles"/>
并在您的代码中:
<many-to-many field="articles" target-entity="Article" mapped-by="tags"/>
生成课程后,您可以双向添加和获取标签或文章,双向。
请记住,如果要从文章中删除标记,则必须在文章和标记类中实现自定义方法,如下所示:
在文章课程中:
public function removeTag(\YourBundle\Entity\Tag $tag){
return $this->tags->removeElement($tag);
}
在标记类中:
public function removeArticle(\YourBundle\Entity\Article $article){
return $this->articles->removeElement($article);
}