GeminiDB Redis 在商品相关性分析的应用
Redis提供了丰富的数据结构(如集合、有序集合、哈希表等),本文以电商场景为背景,介绍了如何利用Redis的数据结构来构建网购商品相关性分析的程序。您可以使用云数据库 GeminiDB Redis接口尝试下面的案例。
使用场景
可以根据同时出现在用户的购物车中的某些商品来分析商品相关性。这种分析对于电商行业至关重要,因为能够帮助商家洞察用户的购买习惯。例如:
- 在商品详情页,为用户推荐与当前商品经常一起购买的其他商品。
- 在购物车页面,当用户添加某件商品后,推荐与之搭配的其他商品。
- 在货架陈列时,将经常一起购买的商品摆放在一起,方便用户选购。
数据结构设计
- 商品浏览记录
记录用户浏览商品的行为,可以使用 Redis 的"SET"数据结构来存储用户浏览过的商品ID。
- Key:user:<user_id>:viewed
- Value:商品ID的集合。
示例:
用户ID为123的用户浏览了商品ID为1001,1002,1003的商品。
user:123:viewed -> {1001, 1002, 1003}
- 2.2 商品购买记录
记录用户购买商品的行为,同样可以使用"SET"数据结构。
- Key:user:<user_id>:purchased
- Value:商品ID的集合。
示例:
用户ID为123的用户购买了了商品ID为1001,1005的商品。
user:123:purchased -> {1001, 1005}
- 2.3 商品相关性计数
记录商品之间的相关性,可以使用 Redis 的"ZSET"(有序集合)来存储商品之间的共现次数。
- Key:product:<product_id>:related
- Value:与该商品相关的其他商品ID及其共现次数。
示例:
与商品1001相关的其他商品ID及其共现次数。
product:1001:related -> {1002:5, 1003:3, 1005:2}
数据收集
- 用户浏览行为
每当用户浏览一个商品时,将商品ID添加到用户的浏览记录集合中。C++代码示例如下:
void recordView(int user_id, int product_id) { std::cout << "User ID " << user_id << " has viewed Product ID " << product_id << std::endl; redis.sadd("user:" + std::to_string(user_id) + ":viewed", std::to_string(product_id)); }
- 用户购买行为
每当用户购买一个商品时,将商品ID添加到用户的购买记录集合中。C++代码示例如下:
void recordPurchase(int user_id, int product_id) { std::cout << "User ID " << user_id << " has purchased Product ID " << product_id << std::endl; redis.sadd("user:" + std::to_string(user_id) + ":purchased", std::to_string(product_id)); }
查询接口
查询相关商品:根据商品ID,查询与该商品最相关的其他商品。C++代码示例如下:
std::vector<std::pair<std::string, double>> getRelatedProducts(int product_id) { std::vector<std::pair<std::string, double>> result; redis.zrevrange("product:" + std::to_string(product_id) + ":related", 0, -1, std::back_inserter(result)); return result; }
C++完整示例代码
以下是完整的示例代码,使用 C++的redis客户端redis++实现。
#include <iostream> #include <iterator> #include <set> #include <vector> #include <string> #include <utility> #include "sw/redis++/redis++.h" using namespace sw::redis; auto redis = Redis("tcp://127.0.0.1:6379"); void recordView(int user_id, int product_id) { std::cout << "User ID " << user_id << " has viewed Product ID " << product_id << std::endl; redis.sadd("user:" + std::to_string(user_id) + ":viewed", std::to_string(product_id)); } void recordPurchase(int user_id, int product_id) { std::cout << "User ID " << user_id << " has purchased Product ID " << product_id << std::endl; redis.sadd("user:" + std::to_string(user_id) + ":purchased", std::to_string(product_id)); } void updateRelatedProducts(int user_id) { std::set<std::string> viewed_products; redis.smembers("user:" + std::to_string(user_id) + ":viewed", std::inserter(viewed_products, viewed_products.end())); std::set<std::string> purchased_products; redis.smembers("user:" + std::to_string(user_id) + ":purchased", std::inserter(purchased_products, purchased_products.end())); for (const auto& product_id : viewed_products) { for (const auto& related_product_id : viewed_products) { if (product_id != related_product_id) { // 浏览的权重为1 redis.zincrby("product:" + product_id + ":related", 1, related_product_id); } } } for (const auto& product_id : purchased_products) { for (const auto& related_product_id : purchased_products) { if (product_id != related_product_id) { // 购买行为权重更高 redis.zincrby("product:" + product_id + ":related", 2, related_product_id); } } } } std::vector<std::pair<std::string, double>> getRelatedProducts(int product_id) { std::vector<std::pair<std::string, double>> result; redis.zrevrange("product:" + std::to_string(product_id) + ":related", 0, -1, std::back_inserter(result)); return result; } int main() { int user_id = 123; // 模拟用户行为 recordView(user_id, 1001); recordView(user_id, 1002); recordView(user_id, 1003); recordView(user_id, 1004); recordView(user_id, 1005); recordPurchase(user_id, 1001); recordPurchase(user_id, 1005); // 根据用户行为更新商品相关性信息 updateRelatedProducts(user_id); // 查询与商品1001相关商品 int product_id = 1001; auto related_products = getRelatedProducts(product_id); std::cout << "Product ID " << product_id << "'s related product is: " << std::endl; for (const auto& [product_id, score] : related_products) { std::cout << "Product ID: " << product_id << ", Score: " << score << std::endl; } return 0; }
运行结果如下: