1

i have 4 rating attributes (Admin->Shops->Attribut->Rating), like "Price", "Scent" and so on. It looks like this:

enter image description here

But it is impossible to find a way, how i can get a summary/data for all ratings, like:

Duft 3,5/5 stars (40 votes)

Wirksamkeit 4,3/5 stars (41 votes)

.... and so on.

$ratingCollectionFactory = $objectManager->get('Magento\Review\Model\ResourceModel\Rating\CollectionFactory'); $ratingCollection = $ratingCollectionFactory->create() ->addEntityFilter( 'product', $product->getId() ) ->setPositionOrder()->setStoreFilter( $storeId) ->addFieldToFilter('is_active',true) ->setPositionOrder('desc', true); echo "<pre>"; print_r($ratingCollection->getData()); 

This results in an array:

Array ( [0] => Array ( [rating_id] => 1 [entity_id] => 1 [rating_code] => Gesamtbewertung [position] => 4 [is_active] => 1 [entity_code] => product ) [1] => Array ( [rating_id] => 6 [entity_id] => 1 [rating_code] => Textur [position] => 3 [is_active] => 1 [entity_code] => product ) 

This only shows the attributs data, but i couldnt find a way to get a summary for the votes/ the votes data, like average count, count totals...

Can someone help?

1 Answer 1

0

The rating tables rating and rating_option_vote need to be joined with the review table / collection to get the summary of the product votes/ratings count, average rating for each of the product rating parameter like (price, quality, value etc)

You can use the following working psuedo code to get the product average ratings

$productId = 162323; // replace with your product id $storeId = 1; // replace with your store id $connection = $resource->getConnection(\Magento\Framework\App\ResourceConnection::DEFAULT_CONNECTION); // Get review collection $reviewCollectionFactory = $ObjectManager->create('\Magento\Review\Model\ResourceModel\Review\CollectionFactory'); $reviewCollection = $reviewCollectionFactory->create(); $reviewCollection ->addStoreFilter($storeId ?: 1) ->addStatusFilter(\Magento\Review\Model\Review::STATUS_APPROVED); if ($productId) { $reviewCollection->addEntityFilter('product', $productId); } // Join with rating vote table to get individual ratings try { $reviewCollection->getSelect()->reset(\Zend_Db_Select::COLUMNS); $reviewCollection->getSelect()->joinLeft( ['rv' => $connection->getTableName('rating_option_vote')], 'main_table.review_id = rv.review_id', [] ) ->joinLeft( ['r' => $connection->getTableName('rating')], 'rv.rating_id = r.rating_id', [] ) ->columns([ 'product_id' => 'main_table.entity_pk_value', 'rating_code' => 'r.rating_code', 'avg_rating' => new \Zend_Db_Expr('AVG(rv.percent)'), 'rating_count' => new \Zend_Db_Expr('COUNT(rv.vote_id)'), 'total_reviews' => new \Zend_Db_Expr('COUNT(DISTINCT main_table.review_id)'), ]) ->group(['main_table.entity_pk_value', 'r.rating_code']); } catch (\Exception $e) { echo 'Exception : ' . $e->getMessage() . PHP_EOL; } catch (\Error $e) { echo 'Error : ' . $e->getMessage() . PHP_EOL; } echo 'Product Reviews with Ratings Count : '.$reviewCollection->getSize() . PHP_EOL; $productRatingsCollection = $reviewCollection; $result = []; foreach ($productRatingsCollection as $item) { $productId = $item->getData('product_id'); $ratingCode = $item->getData('rating_code'); if (!isset($result[$productId])) { $result[$productId] = [ 'product_id' => $productId, 'total_reviews' => $item->getData('total_reviews'), 'ratings' => [] ]; } $result[$productId]['ratings'][$ratingCode] = [ 'average' => round($item->getData('avg_rating'), 2), 'count' => $item->getData('rating_count'), 'percentage' => round($item->getData('avg_rating'), 1) . '%' ]; } echo 'Average Product Rating : '.print_r($result,true) . PHP_EOL; 

Note: The above code is a reference code to be used only in development. It needs to be refactored / adjusted (like replacing the direct usage of ObjectManager with Class DI and removing the echo statements) according to the Magento Coding Standards and Best Practices recommended.

4
  • Works perfectly, thanks. I cannot upvote your answer, so you can upvote your answer by yourself if possible ;) Commented Jun 26 at 9:12
  • @steve_steve be careful of the language you use. It's important to familiarize yourself with the community guidelines, if you don’t yet have enough points to upvote, that’s perfectly normal. As the author of the question, you are absolutely allowed to accept an answer, which you’ve done and that’s great. I kindly ask you to revise your comment quickly so it remains constructive. Commented Jun 26 at 14:54
  • @PЯINCƎ But I didn't really use bad language, did I? I also can't edit it anymore.I've been registered here for X years and a programmer for 25, and I've wanted to contribute constructively many, many times, but I wasn't allowed to reply or vote or anything. I don't have time to deal with how and where to get “reputations” and for what, especially since it's usually not done “just like that”. I'm not going to obsessively make up topics or anything. It seems far outdated to me now, as if there have been no other options for many years. I know this is the wrong place, but I wanted to answer you. Commented Jun 26 at 16:10
  • @steve_steve It was your criticism of the Stack Exchange voting system that bothered me, as this isn't the appropriate place for it. I’ve updated your comment accordingly. I invite you to take a few minutes to read this article magento.stackexchange.com/help/privileges/vote-up. And you are of course always welcome on SE. Commented Jun 26 at 21:13

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.