场景介绍

云数据库 Redis 版在功能上与 Redis 基本一致,因此很容易利用它来实现一个网上商城的商品相关性分析程序。

商品的相关性就是某个产品与其他另外某商品同时出现在购物车中的情况。这种数据分析对于电商行业是很重要的,可以用来分析用户购买行为。例如:

  • 在某一商品的 detail 页面,推荐给用户与该商品相关的其他商品;

  • 在添加购物车成功页面,当用户把一个商品添加到购物车,推荐给用户与之相关的其他商品;

  • 在货架上将相关性比较高的几个商品摆放在一起。

利用云数据库 Redis 版的有序集合,为每种商品构建一个有序集合,集合的成员为和该商品同时出现在购物车中的商品,成员的 score 为同时出现的次数。每次 A 和 B 商品同时出现在购物车中时,分别更新云数据库 Redis 版中 A 和 B 对应的有序集合。

代码示例

package shop.kvstore.aliyun.com;
import java.util.Set;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Tuple;
    public class AliyunShoppingMall {
        public static void main(String[] args) 
        {
            //ApsaraDB for Redis的连接信息,从控制台可以获得
            String host = "xxxxxxxx.m.cnhza.kvstore.aliyuncs.com";
            int port = 6379;
            Jedis jedis = new Jedis(host, port);
            try {
                //ApsaraDB for Redis的实例密码
                String authString = jedis.auth("password");//password
                if (!authString.equals("OK"))
                {
                    System.err.println("AUTH Failed: " + authString);
                    return;
                }
                //产品列表
                String key0="阿里云:产品:啤酒";
                String key1="阿里云:产品:巧克力";
                String key2="阿里云:产品:可乐";
                String key3="阿里云:产品:口香糖";
                String key4="阿里云:产品:牛肉干";
                String key5="阿里云:产品:鸡翅";
                final String[] aliyunProducts=new String[]{key0,key1,key2,key3,key4,key5};
                //初始化,清除可能的已有旧数据
                for (int i = 0; i < aliyunProducts.length; i++) {
                    jedis.del(aliyunProducts[i]);
                }
                //模拟用户购物
                for (int i = 0; i < 5; i++) {//模拟多人次的用户购买行为
                    customersShopping(aliyunProducts,i,jedis);
                }
                System.out.println();
                //利用ApsaraDB for Redis来输出各个商品间的关联关系
                for (int i = 0; i < aliyunProducts.length; i++) {
                    System.out.println(">>>>>>>>>>与"+aliyunProducts[i]+"一起被购买的产品有<<<<<<<<<<<<<<<");
                    Set<Tuple> relatedList = jedis.zrevrangeWithScores(aliyunProducts[i], 0, -1);
                    for (Tuple item : relatedList) {  
                        System.out.println("商品名称:"+item.getElement()+", 共同购买次数:"+Double.valueOf(item.getScore()).intValue());
                    }  
                    System.out.println();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }finally{
                jedis.quit();
                jedis.close();
            }
        }
        private static void customersShopping(String[] products, int i, Jedis jedis) {
            //简单模拟3种购买行为,随机选取作为用户的购买选择
            int bought=(int)(Math.random()*3);
            if(bought==1){
                //模拟业务逻辑:用户购买了如下产品
                System.out.println("用户"+i+"购买了"+products[0]+","+products[2]+","+products[1]);
                //将产品之间的关联情况记录到ApsaraDB for Redis的SortSet之中
                jedis.zincrby(products[0], 1, products[1]);
                jedis.zincrby(products[0], 1, products[2]);
                jedis.zincrby(products[1], 1, products[0]);
                jedis.zincrby(products[1], 1, products[2]);
                jedis.zincrby(products[2], 1, products[0]);
                jedis.zincrby(products[2], 1, products[1]);
            }else if(bought==2){
                //模拟业务逻辑:用户购买了如下产品
                System.out.println("用户"+i+"购买了"+products[4]+","+products[2]+","+products[3]);
                //将产品之间的关联情况记录到ApsaraDB for Redis的SortSet之中
                jedis.zincrby(products[4], 1, products[2]);
                jedis.zincrby(products[4], 1, products[3]);
                jedis.zincrby(products[3], 1, products[4]);
                jedis.zincrby(products[3], 1, products[2]);
                jedis.zincrby(products[2], 1, products[4]);
                jedis.zincrby(products[2], 1, products[3]);
            }else if(bought==0){
                //模拟业务逻辑:用户购买了如下产品
                System.out.println("用户"+i+"购买了"+products[1]+","+products[5]);
                //将产品之间的关联情况记录到ApsaraDB for Redis的SortSet之中
                jedis.zincrby(products[5], 1, products[1]);
                jedis.zincrby(products[1], 1, products[5]);
            }
        }
    }

运行结果

在输入了正确的云数据库 Redis 版实例访问地址和密码之后,运行以上 Java 程序,输出结果如下:

用户0购买了阿里云:产品:巧克力,阿里云:产品:鸡翅
用户1购买了阿里云:产品:牛肉干,阿里云:产品:可乐,阿里云:产品:口香糖
用户2购买了阿里云:产品:啤酒,阿里云:产品:可乐,阿里云:产品:巧克力
用户3购买了阿里云:产品:牛肉干,阿里云:产品:可乐,阿里云:产品:口香糖
用户4购买了阿里云:产品:巧克力,阿里云:产品:鸡翅
>>>>>>>>>>与阿里云:产品:啤酒一起被购买的产品有<<<<<<<<<<<<<<<
商品名称:阿里云:产品:巧克力, 共同购买次数:1
商品名称:阿里云:产品:可乐, 共同购买次数:1
>>>>>>>>>>与阿里云:产品:巧克力一起被购买的产品有<<<<<<<<<<<<<<<
商品名称:阿里云:产品:鸡翅, 共同购买次数:2
商品名称:阿里云:产品:啤酒, 共同购买次数:1
商品名称:阿里云:产品:可乐, 共同购买次数:1
>>>>>>>>>>与阿里云:产品:可乐一起被购买的产品有<<<<<<<<<<<<<<<
商品名称:阿里云:产品:牛肉干, 共同购买次数:2
商品名称:阿里云:产品:口香糖, 共同购买次数:2
商品名称:阿里云:产品:巧克力, 共同购买次数:1
商品名称:阿里云:产品:啤酒, 共同购买次数:1
>>>>>>>>>>与阿里云:产品:口香糖一起被购买的产品有<<<<<<<<<<<<<<<
商品名称:阿里云:产品:牛肉干, 共同购买次数:2
商品名称:阿里云:产品:可乐, 共同购买次数:2
>>>>>>>>>>与阿里云:产品:牛肉干一起被购买的产品有<<<<<<<<<<<<<<<
商品名称:阿里云:产品:可乐, 共同购买次数:2
商品名称:阿里云:产品:口香糖, 共同购买次数:2
>>>>>>>>>>与阿里云:产品:鸡翅一起被购买的产品有<<<<<<<<<<<<<<<
商品名称:阿里云:产品:巧克力, 共同购买次数:2