记录使用Spark计算订单明细表销量排行榜的实现

一、引入相关依赖(版本很重要)

<!--以下版本经过测试验证-->
<dependency>
	<groupId>org.apache.spark</groupId>
	<artifactId>spark-core_2.12</artifactId>
	<version>3.5.3</version>
</dependency>
<dependency>
	<groupId>org.apache.spark</groupId>
	<artifactId>spark-sql_2.12</artifactId>
	<version>3.5.3</version>
</dependency>
<dependency>
	<groupId>io.netty</groupId>
	<artifactId>netty-all</artifactId>
	<version>4.1.58.Final</version>
</dependency>
<dependency>
	<groupId>org.codehaus.janino</groupId>
	<artifactId>janino</artifactId>
	<version>3.1.6</version>
</dependency>

二、实现Spark编码

  • ProductRanking.java
public class ProductRanking {
    private Long skuId;
    private String goodsName;
    private Double totalQuantity;
    private Double totalSales;

    public ProductRanking(Long skuId, String goodsName, Double totalQuantity, Double totalSales) {
        this.skuId = skuId;
        this.goodsName = goodsName;
        this.totalQuantity = totalQuantity;
        this.totalSales = totalSales;
    }

    public Long getSkuId() {
        return skuId;
    }

    public void setSkuId(Long skuId) {
        this.skuId = skuId;
    }

    public String getGoodsName() {
        return goodsName;
    }

    public void setGoodsName(String goodsName) {
        this.goodsName = goodsName;
    }

    public Double getTotalQuantity() {
        return totalQuantity;
    }

    public void setTotalQuantity(Double totalQuantity) {
        this.totalQuantity = totalQuantity;
    }

    public Double getTotalSales() {
        return totalSales;
    }

    public void setTotalSales(Double totalSales) {
        this.totalSales = totalSales;
    }
}
  • SparkJob.java
public class SparkJob {
    public List<ProductRanking> getRanking(){
        // 初始化 SparkSession
        SparkSession spark = SparkSession.builder()
                .appName("Order Item Ranking")
                .master("local[*]")  // 使用本地模式
                .getOrCreate();

        // MySQL JDBC 连接配置
        String jdbcUrl = "jdbc:mysql://localhost:3306/atest?useUnicode=true&characterEncoding=utf8&useSSL=false";
        Properties jdbcProps = new Properties();
        jdbcProps.put("user", "root");
        jdbcProps.put("password", "123456");
        jdbcProps.put("driver", "com.mysql.jdbc.Driver");

        // 设置查询条件:假设要查询 2023 年 1 月 1 日之后的订单
        String query = "(SELECT * FROM nasi_mts_trade_order_item ) AS order_item_filtered";

        // 从 MySQL 中读取符合条件的 order_item 表数据
        Dataset<Row> orderItemDF = spark.read()
                .jdbc(jdbcUrl, query, jdbcProps);

        // 显示数据的前几行,检查数据是否加载正确
//        orderItemDF.show();

        // 统计每个商品的销量
        Dataset<Row> productRankingDF = orderItemDF.groupBy("sku_id", "goods_name")
                .agg(
                        functions.sum("net_weight").alias("total_quantity"),
                        functions.sum(functions.col("net_weight").multiply(functions.col("goods_price"))).alias("total_sales")
                )
                .orderBy(functions.col("total_quantity").desc())  // 按销量降序排序
                .limit(10);  // 获取销量前10名

        // 显示商品排名
//        productRankingDF.show();

        // 转换为 JSON 并映射为 Java 对象
        List<Row> rows = productRankingDF.collectAsList();

        // 将每一行映射为 com.cnnasi.erp.mts.spark.ProductRanking 对象
        List<ProductRanking> ra = rows.stream().map(row -> new ProductRanking(
                row.getAs("sku_id"),
                row.getAs("goods_name"),
                row.getAs("total_quantity"),
                row.getAs("total_sales")
        )).collect(Collectors.toList());
        log.info(JSONObject.toJSONString(ra));
        // 停止 SparkSession
        spark.stop();
        return ra;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老齐谈电商

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值