我将 Symfony2 与 Doctrine2 和 MySQL 一起使用。
我创建了 2 个实体:
- 文章
- 标签之间有一个多对多的链接。
我正在尝试从标签 ID 列表中获取文章的 OR 和 AND。
一个例子可能更好:
- 文章 1 <-> 标签 1、标签 2
- 第 2 条 <-> 标记 2、标记 3、标记 4
- 第 3 条 <-> 标记 1、标记 4
我会从我的标签 ID [2, 3] 列表中,执行 AND 和 OR 请求,以获取一些文章:
- AND => [Article2] 是唯一包含这两个标签的。
- OR => [Article1, Article2] 是唯一具有 tag2 和 tag3 的
我成功地使用循环在 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 调用。我确信在存储库中有适当的方法来做到这一点!