2015-10-29 42 views
3

如何獲取查詢中最活躍的博客標記?Silverstripe ORM:按美元數排序belongs_many_many關係

我有這個兩個數據對象:

class BlogTag extends DataObject { 

//... 

    /** 
    * @var array 
    */ 
    private static $belongs_many_many = array(
     'BlogPosts' => 'BlogPost', 
    ); 

class BlogPost extends Page { 

//... 

    /** 
    * @var array 
    */ 
    private static $many_many = array(
     'Tags' => 'BlogTag', 
    ); 

現在我不知道我怎樣才能與他們有多少博客文章涉及下令所有BlogTags一個DataList。這就是我已經,但不知何故,我不明白如何通過BlogPosts.Count()進行排序:

public function getPopularBlogTags($limit = 5) { 
    $tags = BlogTag::get() 
     ->sort('BlogPosts.Count()') //doesn't work 
     ->limit($limit); 

    return $tags; 
} 

回答

5

發現在IRC上的幫助(感謝巴里和標記)

public function getPopularBlogTags($limit = 5) { 
    $tags = BlogTag::get() 
     ->setQueriedColumns(['ID', 'Title', 'Count(*)']) 
     ->leftJoin('BlogPost_Tags','bpt.BlogTagID = BlogTag.ID','bpt') 
     ->sort('Count(*) DESC') 
     ->alterDataQuery(function($query){ 
      $query->groupBy('BlogTag.ID'); 
     }) 
     ->limit($limit); 

    return $tags; 
} 
的解決方案

並在模板中:

<% loop $PopularBlogTags %> 
     <a href="$Link" title="$Title">$Title ($BlogPosts.Count())</a> 
     <% if not $Last %> | <% end_if %> 
    <% end_loop %> 
+0

這對我有幫助,謝謝你們!請注意,在我看來,您可以刪除' - > setQueriedColumns()'部分,因爲在sort子句中包括COUNT(*)'會導致該列自動添加。 – Jono

+0

我認爲' - > setQueriedColumns()'告訴DB也只是返回當前動作所需的數據,所以它不會返回_all_數據...它應該更快,然後..? – wmk

+0

你會這樣想,但它似乎並不適合我。如果我查看'$ tags-> sql()',那麼結果與使用或不使用' - > setQueriedColumns(['ID','Title','Count(*)'])'部分完全相同。我不確定該方法的名稱是否具有誤導性,它實際上只是*添加了*查詢的列,或者它是否被覆蓋。無論如何,我認爲試圖限制查詢列在一般情況下不是最佳選擇,因爲這意味着您無法訪問模板中的完整對象,並創建更緊密的耦合/更少的靈活性。 – Jono