【问题标题】:Select only specific portion of OneToMany joined collection仅选择 OneToMany 加入集合的特定部分
【发布时间】:2016-05-06 06:07:04
【问题描述】:

我是 symfony 的新手,如果这真的很容易回答,我很抱歉。

为了举例,我重写了代码 sn-ps,就好像我在写博客一样。
我有一个BlogPost 实体,其中包含BlogComments 的集合,注释如下:

 /**
 * @OneToMany(targetEntity="BlogComment", mappedBy="post")
 */
private $comments;

从我业余的角度来看,Doctrine 喜欢使用完整的对象,所以这个集合要么没有初始化,要么在我使用对它的引用时延迟加载。

我想你可以想象当我的每个BlogPosts 至少有 500 个Blogcomments 并且每当我触摸$comments 变量时它们都会被初始化时的开销和内存需求。

我想要实现的是列出 ie。 50 篇博文,每篇都有 20 个最新的 cmets(没有内存爆炸)。此外,我希望能够仅显示“喜欢”最多的前 20 个 cmets(或者通常仅根据某些标准选择一个子集)。

是否有任何普遍推荐和干净的方法来实现这种功能?当我实现这一点时,是否使用这种“不完整”或“修改”的实体会破坏我的逻辑(当从子集中更新/删除项目并保留它时)?我认为对此的解决方案可能是自定义存储库中的一种方法,但我仍然看不到它背后的想法。

提前谢谢你的回答,我真的很好奇你能想出什么样的解决方案。

【问题讨论】:

    标签: php doctrine symfony


    【解决方案1】:

    Doctrine 不适合处理大列表对象。这将比一个经典的 SQL 查询慢得多,然后是while ($row = $stmt->fetch())。有时,最好执行本机查询。 50 篇博文 * 20 cmets = 1000 个对象,如果您获得每个结果的用户名,则可能更多。

    无论如何,您都需要使用本机查询,因为我认为您无法使用纯 DQL 查询获得每篇博文的 20 cmets。您将需要执行一些连接子查询以限制为 20 个 cmets,有关更多信息,请参阅此帖子:MySQL JOIN with LIMIT 1 on joined table

    完成本机查询后,如果您确实需要对象,可以使用 ResultSetMappingBuilder 将结果绑定到 Doctrine 实体:http://doctrine-orm.readthedocs.org/projects/doctrine-orm/en/latest/reference/native-sql.html#resultsetmappingbuilder

    【讨论】:

    • 感谢您的回答,我一定会调查的。我可以毫无问题地用 SQL 编写查询。 :) 我的另一个想法是调用另一个存储库来获取帖子的BlogComments,然后手动将它们分配给每个$comments 变量BlogPost...这是 symfony/doctrine 的错误思维方式吗?
    • 这不是错误的方法,但我最好只用一个好的查询来做到这一点:为您的数据库减少工作量,并更好地在 Doctrine 方面使用缓存。就 Doctrine 而言,一个或多个查询不会改变很多事情,因为它的工作是获取一行(一个数组)并将其转换为 PHP 对象。他真的不在乎你是用一个还是几个查询来做。
    猜你喜欢
    • 2012-12-10
    • 1970-01-01
    • 1970-01-01
    • 2015-11-03
    • 1970-01-01
    • 2021-09-26
    • 1970-01-01
    • 1970-01-01
    • 2015-05-08
    相关资源
    最近更新 更多