Ignore:
Timestamp:
Jul 25, 2011, 8:04:50 PM (13 years ago)
Author:
rvelices
Message:

feature 2384: improve average rating calculation (still need to update language files)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/functions_rate.inc.php

    r8728 r11827  
    117117  pwg_query($query);
    118118
    119   // update of images.average_rate field
     119  return update_rating_score($image_id);
     120}
     121
     122
     123/* update images.average_rate field
     124  * we use a bayesian average (http://en.wikipedia.org/wiki/Bayesian_average) with
     125C = average number of rates per item
     126m = global average rate (all rates)
     127
     128 * param int $element_id optional, otherwise applies to all
     129 * @return array(average_rate, count) if element_id is specified
     130*/
     131function update_rating_score($element_id = false)
     132{
    120133  $query = '
    121 SELECT COUNT(rate) AS count
    122      , ROUND(AVG(rate),2) AS average
    123   FROM '.RATE_TABLE.'
    124   WHERE element_id = '.$image_id.'
    125 ;';
    126   $row = pwg_db_fetch_assoc(pwg_query($query));
    127   $query = '
    128 UPDATE '.IMAGES_TABLE.'
    129   SET average_rate = '.$row['average'].'
    130   WHERE id = '.$image_id.'
    131 ;';
    132   pwg_query($query);
    133   return $row;
     134SELECT element_id,
     135    COUNT(rate) AS rcount,
     136    SUM(rate) AS rsum
     137  FROM '.RATE_TABLE.'
     138  GROUP by element_id';
     139
     140  $all_rates_count = 0;
     141  $all_rates_avg = 0;
     142  $item_ratecount_avg = 0;
     143  $by_item = array();
     144
     145  $result = pwg_query($query);
     146  while ($row = pwg_db_fetch_assoc($result))
     147  {
     148    $all_rates_count += $row['rcount'];
     149    $all_rates_avg += $row['rsum'];
     150    $by_item[$row['element_id']] = $row;
     151  }
     152
     153  $all_rates_avg /= $all_rates_count;
     154  $item_ratecount_avg = $all_rates_count / count($by_item);
     155
     156  $updates = array();
     157  foreach ($by_item as $id => $rate_summary )
     158  {
     159    $score = ( $item_ratecount_avg * $all_rates_avg + $rate_summary['rsum'] ) / ($item_ratecount_avg + $rate_summary['rcount']);
     160    $score = round($score,2);
     161    if ($id==$element_id)
     162    {
     163      $return = array(
     164        'score' => $score,
     165        'average' => round($rate_summary['rsum'] / $rate_summary['rcount'], 2),
     166        'count' => $rate_summary['rcount'],
     167        );
     168    }
     169    $updates[] = array( 'id'=>$id, 'average_rate'=>$score );
     170  }
     171  mass_updates(
     172    IMAGES_TABLE,
     173    array(
     174      'primary' => array('id'),
     175      'update' => array('average_rate')
     176      ),
     177    $updates
     178    );
     179
     180  //set to null all items with no rate
     181  if ( !isset($by_item[$element_id]) )
     182  {
     183    $query='
     184SELECT id FROM '.IMAGES_TABLE .'
     185  LEFT JOIN '.RATE_TABLE.' ON id=element_id
     186  WHERE element_id IS NULL AND average_rate IS NOT NULL';
     187
     188    $to_update = array_from_query( $query, 'id');
     189
     190    if ( !empty($to_update) )
     191    {
     192      $query='
     193UPDATE '.IMAGES_TABLE .'
     194  SET average_rate=NULL
     195  WHERE id IN (' . implode(',',$to_update) . ')';
     196    pwg_query($query);
     197    }
     198  }
     199
     200  return isset($return) ? $return : array('score'=>null, 'average'=>null, 'count'=>0 );
    134201}
    135202
Note: See TracChangeset for help on using the changeset viewer.