首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何选择在ManyToMany关系中同时具有两个项的行

如何选择在ManyToMany关系中同时具有两个项的行
EN

Stack Overflow用户
提问于 2021-05-12 08:32:44
回答 1查看 54关注 0票数 1

假设我有“新闻”实体,它有ManyToMany“标记”关系

代码语言:javascript
运行
复制
class News
{
    /**
     * @ORM\ManyToMany(targetEntity="App\Domain\Entity\Vocabulary\Tag")
     */
    private Collection $tags;
}

我有这样的疑问:

代码语言:javascript
运行
复制
public function getList(
    array $tags = null,
): Query {
    if (null !== $tags) {
        $qb->andWhere('nt.id IN (:tags)');
        $qb->setParameter('tags', $tags);
    }
}

问题是,当我传递"Tag1“、"Tag2”时,它会选择具有第一个标签或第二个标签的新闻,但不是同时包含两个标签的新闻。如何重写查询以选择同时具有两个标记的新闻?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-05-30 17:02:45

有些事情首先要注意:

对于理论注释,可以使用::class-constant:

代码语言:javascript
运行
复制
use App\Domain\Entity\Vocabulary\Tag;

class News
{
    /**
     * @ORM\ManyToMany(targetEntity=Tag::class)
     */
    private Collection $tags;
 }

如果$tags数组为空,则将抛出一个异常,因为空值集无效,至少在mysql中是这样的:

代码语言:javascript
运行
复制
nt.id IN () # invalid!

现在谈一谈问题:

使用SQL-聚合函数COUNTGROUP BY,我们可以计算所有新闻的标记数。加上允许标记的条件,每个新闻的标记数必须等于标记数组中的标记数:

代码语言:javascript
运行
复制
/**
 * @var EntityManagerInterface
 */
private $manager;

...

/**
 * @param list<Tag> $tags - Optional tag filter // "list" is a vimeo psalm annotation.
 *
 * @return list<News>
 */
 public function getNews(array $tags = []): array 
 {
    $qb = $this->manager
        ->createQueryBuilder()
        ->from(News::class, 'news')
        ->select('news')
    ;

    if(!empty($tags)) {
        $tagIds = array_unique(
            array_map(static function(Tag $tag): int {
                return $tag->getId();
            }) // For performance reasons, give doctrine ids instead of objects.
        ); // Make sure duplicate tags are handled.

        $qb
            ->join('news.tags', 'tag')
            ->where('tag IN (:tags)') 
            ->setParameter('tags', $tagIds) 
            ->addSelect('COUNT(tag) AS HIDDEN numberOfTags') 
            ->groupBy('news') 
            ->having('numberOfTags = :numberOfTags') 
            ->setParameter('numberOfTags', count($tags)) 
        ;
    }

    return $qb
        ->getQuery()
        ->getResult()
    ;
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67499992

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档