繁体   English   中英

如何查询相关实体但返回根实体?

[英]How to query on related entities but return root entities?

这是一个假设的问题,因为我试图了解Doctrine ORM,并且很难复制我在纯SQL中所做的事情。

假设我在标签和帖子之间有一个简单的ManytoMany关系。 他们会映射,以便Post::tags是拥有者, Tag::posts是反向映射。

我理解,使用Doctrine的DQL,我可以选择包含其标签的帖子,或使用以下2个查询引用其帖子的标签

(1) SELECT p, t FROM MyBundle:Post p JOIN p.tags t WHERE p.id = :id

(2) SELECT t, p FROM MyBundle:Tag t JOIN t.posts p WHERE t.id = :id

但是,当我想通过多个标签获取帖子时,我必须在以下选项中进行选择:

(3) SELECT p, t FROM MyBundle:Post p JOIN p.tags t WHERE t.value IN ('foo','bar')

(4) SELECT t, p FROM MyBundle:Tag t JOIN t.posts p WHERE t.value IN ('foo','bar')

这两个似乎都错了。

使用(3)我想数据库会在将设置减少到标记之前扫描整个帖子表

随着(4)我得到一个标签对象的集合,这是我所追求的反过来。

我尝试了以下内容,因为从逻辑上讲它似乎反映了我在SQL中所做的事情:

SELECT p, pt FROM MyBundle:Tag t JOIN t.posts p JOIN p.tags pt
                 WHERE t.value IN ('foo','bar') GROUP BY p.id

它不起作用,因为Doctrine坚持我选择根实体

选择标签的最佳方法是什么,但将独特的帖子作为完整对象取回?

如果我理解了这个问题,你想要的是选择所有至少有一个标签的帖子,这些标签的值在一个定义的集合中(“foo”,“bar”,...)并忽略所有其他帖子。

让我们从(3)开始:

SELECT p, t FROM MyBundle:Post p JOIN p.tags t WHERE t.value IN ('foo','bar')

在MySQL中,这意味着:“选择所有具有值为foo或bar的标记的帖子”。

但是在DQL中,这意味着“选择所有帖子并仅附加值为foo或bar的标签”。 这意味着查询将返回所有帖子的集合,但过滤了标签。 这种行为差异是由于doctrine必须使用数据库层返回的数组创建对象。 使用JOIN进行MySQL查询时,结果将是一个包含重复项的数组。 但是,在对象世界中,必须在单个Post对象中合并重复的帖子...

我相信您的查询的解决方案是在进行连接时进行过滤:

SELECT p,t FROM MyBundle:Post p JOIN p.tags t WITH t.value IN ('foo', 'bar')

你可以理解WITH DQL子句,好像它在ON MySQL子句中添加了一个条件。 即上面的查询类似于下面的MySQL查询:

SELECT p.*, t.* FROM posts AS p JOIN posts_tags AS pt ON pt.post_id = p.id JOIN tags AS t ON pt.tag_id = t.id AND t.value IN ("foo", "bar")

注意不再有WHERE子句。 条件在JOIN条件子句中移动了......

希望这可以帮助 ;-)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM