lam*_*ade 4 php mysql symfony doctrine-orm
我有一个page
由多个container
s 组成的实体.在那些容器中,用户可以链接news list
.那些news list
再次包含news items
.
现在,我想搜索news items
,但我需要page
的news list
是在挂为好.
我试过这个:
$query = $this->getEntityManager()->createQuery('
SELECT p, c, n, i
FROM VendorNameBundle:Page p
LEFT JOIN p.container c
LEFT JOIN c.news n
LEFT JOIN n.items i
WHERE i.title LIKE :title
GROUP BY i.id
');
Run Code Online (Sandbox Code Playgroud)
这基本上起作用,因为它给了我正确的页面.但要找到正确的,news item
我必须贯穿所有container
s和他们的news list
s.当然,当我检索所有项目时,我不仅仅是搜索的重要项目.
我怎样才能以优雅的方式解决这个问题?
总结:我需要news items
和他们相应的page
实体.我怎样才能以一种整洁优雅的方式解决这个问题?
注意:如果a news list
在多个页面上列出page
,则结果中的一个就足够了,并不重要.
编辑
以下是评论中要求的关系:
页
/**
* @ORM\OneToMany(targetEntity="Container", mappedBy="page", cascade={"remove"})
* @ORM\OrderBy({"position" = "asc"})
*/
protected $containers;
Run Code Online (Sandbox Code Playgroud)
容器
/**
* @ORM\ManyToOne(targetEntity="Page", inversedBy="containers")
* @ORM\JoinColumn(name="Page_id", referencedColumnName="id")
*/
private $page;
/**
* @ORM\ManyToOne(targetEntity="News", inversedBy="containers")
* @ORM\JoinColumn(name="news_id", referencedColumnName="id", onDelete="SET NULL")
*/
protected $news;
Run Code Online (Sandbox Code Playgroud)
新闻
/**
* @ORM\OneToMany(targetEntity="Container", mappedBy="news")
*/
protected $containers;
Run Code Online (Sandbox Code Playgroud)
因为您正在搜索新闻项目,我建议您使用这些新闻项目直到页面(而不是相反):
SELECT i, n, c, p
FROM VendorNameBundle:Item i
JOIN i.news n
JOIN n.container c
JOIN c.page p
WHERE i.title LIKE :title
Run Code Online (Sandbox Code Playgroud)
此查询确实假设每个新闻项都在新闻列表中,每个新闻列表都在一个容器内,每个容器都在一个页面内.如果不是这样,请使用a LEFT JOIN
而不是a JOIN
,否则你会错过一些新闻.
此查询将为您提供所需的数据,但可能没有按您希望的方式格式化.如果要对每页或新闻列表(等)进行分组,则需要手动(在代码中)执行此操作.
但是,您可以让查询执行某些排序,因此分组(在代码中)变得更容易.以下示例将首先按页面标题排序结果,然后是新闻列表的标题:
SELECT i, n, c, p
FROM VendorNameBundle:Item i
JOIN i.news n
JOIN n.container c
JOIN c.page p
WHERE i.title LIKE :title
ORDER BY p.title ASC, n.title ASC
Run Code Online (Sandbox Code Playgroud)
现在分组可以像这样完成:
$currentPage = null;
$currentNewsList = null;
foreach ($newsItems as $newsItem) {
$newsList = $newsItem->getNews();
$page = $newsList->getContainer()->getPage();
if ($page !== $currentPage) {
$currentPage = $page;
echo '- ' . $page->getTitle() . "\n";
}
if ($newsList !== $currentNewsList) {
$currentNewsList = $newsList;
echo ' - ' . $newsList->getTitle() . "\n";
}
echo ' - ' . $newsItem->getTitle() . "\n";
}
Run Code Online (Sandbox Code Playgroud)
哪个会打印这样的东西:
- Page A
- News list A
- Found news item
- News list C
- Another found news item
- Page B
- News list B
- Yet another found news item
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
212 次 |
最近记录: |