簡體   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