Chapter 19: Review and Rating Systems
Why This Exists
In e-commerce, customers cannot touch, feel, or try on a product before buying it. They rely entirely on Social Proof. A product with a 4.5-star average and 1,000 reviews will massively outsell an identical product with no reviews. The Review and Rating architecture exists to aggregate user feedback, build trust, and directly influence the conversion rate of the catalog. However, because reviews influence money, they are a primary target for manipulation, spam, and fraud.
Real World Problem
A merchant launches a new brand of headphones. A malicious competitor writes a bot that creates 500 fake accounts and submits 500 1-star reviews overnight. The product's average rating plummets to 1.1 stars. Sales drop to zero immediately. If the architecture blindly accepts all reviews and calculates a simple mathematical average, the platform becomes untrustworthy. The real-world problem is building a system that can accurately aggregate millions of data points while filtering out bad actors.
Everyday Analogy
Think of asking for a restaurant recommendation.
- If a random stranger on the street tells you a restaurant is amazing, you might be skeptical (Unverified Review).
- If your best friend, who you know eats there all the time, tells you it's amazing, you trust it completely (Verified Purchase Review).
- If 100 people are shouting outside the restaurant that it's terrible, but none of them have ever been inside, a good bouncer ignores them (Spam Filtering).
Beginner Explanation
A review system lets customers leave a star rating (1 to 5) and write a text comment about a product. The computer takes all the star ratings for a specific product, adds them up, divides by the total number of reviews, and displays the "Average Rating" (e.g., 4.2 Stars) on the product page so new buyers know if it's a good item.
Intermediate Explanation
Architecturally, reviews are tied to a Product and a User.
To combat spam, systems distinguish between:
- Unverified Reviews: Anyone can leave a review.
- Verified Purchase: The system checks the
Orderstable to ensure theuser_idactually bought theproduct_idbefore allowing the review, or it adds a special badge to the UI.
Because product pages are the most viewed pages on an e-commerce site, the system cannot run a SQL query like SELECT AVG(rating) FROM reviews WHERE product_id = X every time the page loads. This would crash the database. The average must be pre-calculated and cached.
Advanced Explanation
At enterprise scale, simple averages are replaced by Bayesian Averages or Weighted Averages. A product with a single 5-star review should not rank higher in search results than a product with 10,000 4.8-star reviews. A Bayesian average pulls low-volume products toward the global mean to provide fairer sorting.
Furthermore, reviews pass through an Asynchronous Moderation Pipeline. When a user submits a review, it goes into a Message Queue. A Machine Learning service (NLP - Natural Language Processing) scans the text for:
- Profanity
- Links to competitor websites
- PII (Someone accidentally pasting their phone number) If it passes, it is published and the cached average is updated. If it fails, it is flagged for manual human review in an admin panel.
Real World Example
Amazon's Review System: Amazon faces the most sophisticated fake-review attacks in the world (e.g., sellers paying people on Facebook to buy their item and leave 5 stars). Amazon's architecture uses graph databases and ML to map relationships. If User A and User B share the same IP address, or frequently review the exact same obscure products within minutes of each other, the algorithm flags them as a "Review Ring" and silently hides their reviews from the global aggregate.
Architecture Design
Here is an Event-Driven Review Moderation and Aggregation pipeline:
graph TD
User[Customer] -->|Submit Review| API[Review API]
API -->|1. Validate Purchase| DB_Order[(Order DB)]
API -->|2. Queue for Moderation| MQ[Message Queue]
MQ --> NLP[Automated NLP Moderator]
NLP -- Approved --> DB_Rev[(Reviews DB)]
NLP -- Flagged --> Admin[Manual Human Review]
DB_Rev -->|Database Trigger / Event| AggWorker[Aggregation Worker]
AggWorker -->|Calculate New Avg| Cache[(Redis / Catalog Cache)]
Shopper[New Shopper] -->|Views Product Page| Cache
Database Design
1. The Reviews Table:
CREATE TABLE reviews (
id UUID PRIMARY KEY,
product_id UUID,
user_id UUID,
rating INT CHECK (rating >= 1 AND rating <= 5),
headline VARCHAR(255),
comment TEXT,
is_verified_purchase BOOLEAN,
status VARCHAR(50) DEFAULT 'PENDING_MODERATION',
created_at TIMESTAMP
);
2. The Aggregates Table (For Fast Reads):
CREATE TABLE product_review_stats (
product_id UUID PRIMARY KEY,
total_reviews INT,
average_rating DECIMAL(3,2),
five_star_count INT,
four_star_count INT,
-- ... etc
last_calculated_at TIMESTAMP
);
API Design
Submit a Review:
POST /api/products/{id}/reviews
Payload: { "rating": 4, "headline": "Great!", "comment": "Fits perfectly." }
Fetch Reviews (With Pagination and Sorting):
GET /api/products/{id}/reviews?sort=highest_rated&limit=10&page=1
Production Considerations
- Eventual Consistency in Averages: When a user submits a 1-star review, the product page's average rating might not drop immediately. The update is processed via background workers. The UI should say "Review submitted and pending approval" rather than immediately refreshing the average.
- Sorting by "Helpful": Users can upvote reviews ("Was this helpful?"). To prevent sorting algorithms from always keeping 10-year-old reviews at the top (because they had 10 years to accumulate votes), algorithms use Time-Decay (e.g., Reddit's Hot algorithm) to ensure recent helpful reviews surface first.
Security Considerations
- XSS (Cross-Site Scripting): Reviews allow users to input raw text that is displayed to thousands of other users. If a hacker inputs
<script>stealCookie()</script>and the frontend renders it unescaped, you have a massive security breach. All review text MUST be strictly sanitized before saving to the database. - Rate Limiting: A single IP address should not be able to submit 100 reviews a minute.
Common Mistakes
- Synchronous Aggregation: Using
COUNT()andAVG()directly on thereviewstable during a page load. This will bring down the database during a high-traffic event. - Deleting Negative Reviews: Allowing merchants to delete 1-star reviews destroys platform trust. Negative reviews should only be removed if they violate content policies (profanity, spam), not because they hurt sales.
Tradeoffs and Alternatives
- Build vs. Buy: Building a review system is easy; building the spam filters, image uploads, and moderation queues is hard. Many platforms use third-party SaaS providers like Yotpo or Bazaarvoice to handle the entire review architecture.
Interview Questions
- Why shouldn't you calculate the average product rating using a SQL
AVG()function on every page load? How do you architect a faster solution? - How do you prevent a malicious script embedded in a review's text comment from executing on a shopper's browser (XSS)?
- What is a "Verified Purchase" review, and how would you validate it programmatically before accepting the review?
Hands-On Exercise
- Go to an Amazon product page.
- Look at the Review distribution chart (the percentage of 5-star vs 1-star).
- Try to reverse engineer the data model required to render that exact chart without hitting the primary reviews table. (Hint: Look at the
product_review_statsschema above).
Key Takeaways
- Reviews are critical for conversion but are the primary vector for platform spam.
- Read performance is paramount: averages and count distributions must be pre-calculated and cached.
- Reviews should pass through an asynchronous moderation pipeline (ML or Human) before publication.
- Never trust user input; strict XSS sanitization is mandatory.
Further Reading
- Bayesian Averages for Rating Systems
- OWASP: Cross Site Scripting (XSS) Prevention