2015-08-31 37 views
0

我們有ShopArticles店,想加入評分系統。Criteria API hasmany的平均關係

我們ShopArticle看起來是這樣的:

class ShopArticle { 
String contUnit = 'STK', orderUnit = 'PCK' 
Double value, tax = 0.19 
String name, description, keyword 
String group1, group2, group3, articleNumber 
String producer 
Boolean unlocked 

static hasMany = [ratings: ShopArticleRating] 
} 

而且評級是這樣的:

class ShopArticleRating { 
String comment 
int rating 
ShopArticle shopArticle 
User user 

static belongsTo = ShopArticle 
} 

現在,我們要篩選的atricle的平均評分,所以我們做了這樣的:

 def shopArticleList = ShopArticleRating.createCriteria().listDistinct { 
      projections { 
       groupProperty("shopArticle") 
      } 
     } 
     def ids = [] 
     shopArticleList.each { shopArticle -> 
      def sum = 0 
      shopArticle.ratings.each { 
       sum += it.rating 
      } 

      if ((sum/shopArticle.ratings.size()) >= filter.rating) { 
       ids.add(shopArticle.id) 
      } 
     } 

    List<ShopArticle> list = ShopArticle.createCriteria().list { 
     if (ids.size() > 0) { 
      'in'("id", ids) 
     } 
    } 

有沒有更好的方法來篩選平均評分?

也許是這樣的:

List<ShopArticle> list = ShopArticle.createCriteria().list { 
createAlias('ratings','r') 
projections { 
    groupProperty('r.rating') 
} 
gt("r.rating",filter.rating) 
} 
+0

你需要每家商店或所有商店的平均評分? – injecteer

回答

0

要不是我,我會一個averageRating屬性添加到ShopArticle類本身。

做數學計算平均值時,該ShopArticle添加/刪除/更改的評分,並分發每個評分輸入/更改進行數學計算的「成本」。十人添加評級,你做數學10次。有一千人在做查詢,你不會做數學1000次。

顯示平均等級只不過是在屏幕上顯示另一個屬性,過濾是微不足道的 - 在查詢數據時沒有額外的工作(我認爲可以肯定會有更多的查詢比添加額定值)。

0

試試這個:

ShopArticleRating.withCriteria { 
    projections { 
     avg("rating") 
     groupProperty("shopArticle") 
    } 
} 

這應該一起給你的文章與對象的平均收視率。

我無法測試的其他方式,但它應該是這樣的:

ShopArticle.withCriteria { 
    projections { 
     ratings { 
      avg("rating) 
     } 
     property("id") 
    } 
} 

這應該給你的文章編號,平均記者評級

另一種方法是一起編寫你自己的SQL語法,它給你絕對的自由來返回你想要的一切。在這種情況下尋找「grails HQL」。有時當我需要執行非常複雜的查詢時,我會觸摸邊框。但在你的情況下,你應該很好。