我有4个表,实体中的属性都相应地映射。我正在尝试查询基于选定标签的文章。
articles => id, title, author_id - NAMESPACE AppBundle/Enity/Article
tags => id, name - NAMESPACE AppBundle/Entity/Tag
article_tags => article_id, tag_id
authors=> id, name - NAMESPACE AppBundle/Entity/Author
我已经弄清楚了如何获得所有的文章,其中标签在article_tags表中具有与它们相关的id,并通过作者id进行过滤。在SQL中,我的查询看起来像这样。
SELECT
articles.title, articles.id, authors.name
FROM
article_tags
INNER JOIN tags
ON article_tags.tag_id = tags.id
INNER JOIN articles
ON article_tags.article_id = article.id
INNER JOIN authors
ON authors.id = articles.author_id
WHERE
tags.id IN (1,2)
我试图建立一个查询,代表上述sql。到目前为止,我的理解是,原则将根据实体中的ORM断言自动挑选所需的关联。但是,我不确定如何将其他实体带入查询。这是我目前掌握的信息。
我的代码在文章的repo是:
$qb = $this->createQueryBuilder('ar')
->select('ar.title, ar.id, au.name')
->from('article_tags', 'at')
->innerJoin('tags', 't', 'WITH', 'at.tag_id = t.id')
->innerJoin('ar', 'WITH', 'at.article_id = ar.id')
->innerJoin('authors', 'au', 'WITH', 'au.id = ar.author_id')
->where('at.id IN (1,2)');
return $qb->getQuery()->getResult();
我已经用'ON'和' with '关键字尝试了上面的代码。
My error is [语义错误]第0行,col 76附近的'标签t WITH at。tag_id':错误:类'tags'未定义。
当你使用Doctrine ORM进行连接时,你不需要指定连接条件,因为它应该在实体的元数据中。
在你的例子中,你有与标签和作者相关的文章,如果你想让标签和作者与你的文章一起,你的查询应该像这样:
// this is in the article repository I'm guessing?
$qb = $this->createQueryBuilder('ar');
$qb->addSelect([ 't', 'au' ])
->join('ar.tags', 't')
->join('ar.authors', 'au')
->where($qb->expr()->in('a.tags', ':tags'))
->setParameter('tags', [ 1, 2 ]);
所以这两个连接语句是关于实体的属性,在本例中是tags
和authors
。在您的文章实体中,您需要按照文档将这些设置为关联。元数据定义了文章与标签和作者的关系,Doctrine(通常)将填补空白。你的查询看起来像它仍然在思考SQL而不是实体和原则(和DQL)。
作为旁注,上面不是一个很好的查询,因为返回的行数将等于标签和作者的数量,您最好在没有选择中的额外实体的情况下执行查询,然后在之后抓取标签(例如通过执行$article->getTags()
)。