一个很好的SQL查询,使用Doctrine2从标签列表中获取项目



我将Symfony2与Doctrine2和MySQL一起使用。

我创建了两个实体:

  • 文章
  • 标记它们之间有着多对多的联系

我正在尝试从标签ID列表中获取文章的OR和and。

举个例子可能更好:

  • 第1<->条Tag1、Tag2
  • 第2条Tag2、Tag3、Tag4
  • 第三条Tag1、Tag4

我会从我的标签ID列表[2,3]中,进行AND和OR请求,以获得一些文章:

  • AND=>[Article2]是唯一包含这两个标签的
  • OR=>[第1条,第2条]是唯一具有标签2和标签3的

我成功地用一个循环对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调用。我相信在存储库中有一种正确的方法可以做到这一点!

请从resources/config文件夹中提供实体定义。您要查找的是双向关联映射。查看文档:

http://docs.doctrine-project.org/en/2.0.x/reference/association-mapping.html#many-到许多双向

在您的文章中:

<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(YourBundleEntityTag $tag){
return $this->tags->removeElement($tag);
}

标签类中:

public function removeArticle(YourBundleEntityArticle $article){
return $this->articles->removeElement($article);
}

相关内容

  • 没有找到相关文章

最新更新