需求

计算订单中,所包含的商品(单品)是否可以组成套包,且得出这个套包在这个订单中的个数。

即:假设某套包的商品为(a,b,c),某订单中购买了(a,b,c,d,a,b,c)五个商品,则这个订单中包含2个这个套包。

之前是将套包维度表和订单事实表进行笛卡尔积,然后用hive的UDF函数计算,但是在实际使用过程中发现速度很慢。了解到spark 2.0之后的第二代钨丝计划对spark内部函数进行了大量优化,可能性能会比hive的UDF函数好点。考虑进行重构,使用spark的UDF函数进行计算。再此之前先使用DF的map算子进行计算。

思路

经过处理的订单表内容包含订单ID字段和购买商品字段,购买商品字段包含该订单所买的所有商品,以逗号隔开,内容大致如下:

Order_ID           Order_Items

1                  a,b,c,d,a,b,c,d
     2                  q,w,e,r
     3                  a,a,s,d,f

套包维度表与订单表相同,包含套包ID和套包内商品:

Head_ID         Head_items

1                  a,b,c,d
     2                  q,w,e
     3                  q,a,s,d

总的来说,这个需求就是求数组A是否包含数组B,并求出包含几个数组B的问题。

  1. 将订单表和套包维度表笛卡尔积。
  2. 对笛卡尔积的每条数据进行计算。
    1. 将两张表的items已逗号分隔,转换成ArrayBuffer。
    2. 判断Order的items个数是否大于Head的items个数,如果大于或等于,进入3;否则不可能包含Head的套包,结束。
    3. 循环判断Head的每个item是否存在Order的items中,如果存在,则删除Order中的该item,并继续判断,直到Head的最后一个Item也存在Order中,则count加1,并返回2;如果不存在,则说明Order中不可能包含Head的所有商品,结束。

实现

1.定义样例类。

package com.zixuan.spark.beancase class HD(hid:String,hitem:String)
case class Order(oid:String,oitem:String)
case class Result(hid:String,hitem:String,oid:String,oitem:String,result: Int)

2.spark代码

package com.zixuan.spark.testimport com.zixuan.spark.bean.{HD, Order, Result}
import org.apache.spark.sql.SparkSession
import org.apache.spark.{SparkConf, SparkContext}object BomCount {def main(args: Array[String]): Unit = {val conf = new SparkConf().setAppName("test").setMaster("local[1]")val context = new SparkContext(conf)//屏蔽spark的info warn信息context.setLogLevel("ERROR")val session = SparkSession.builder().config(conf).getOrCreate()//导入转换DF的隐式转换import session.implicits._val hd =context.textFile("C:\\Users\\zixuan.wu\\Desktop\\sparkTest\\hd.txt").map(s=>s.split(" ")).map(strings=>HD(strings(0),strings(1))).toDF()val order =context.textFile("C:\\Users\\zixuan.wu\\Desktop\\sparkTest\\order.txt").map(s=>s.split(" ")).map(strings=>Order(strings(0),strings(1))).toDF()//val hd = session.sql("select * from xxx")//val order = session.sql("select * from xxx")//val order_product = order.groupBy("order_id","product_id")//笛卡尔积val frame = hd.crossJoin(order)frame.show()//主要计算逻辑val result = frame.map(row => {//将items以逗号切割,并转换成buffervar hitems = row.getAs[String]("hitem").split(",").toBuffervar oitems = row.getAs[String]("oitem").split(",").toBuffer//初始化countvar count = 0//while循环控制标记var continueFlag = 1//导入scala的break包import scala.util.control._//如果oitem的个数大于等于hitem且continueFlag标记为1,则进入循环while (oitems.length >= hitems.length && continueFlag==1){//默认不继续while循环,如果oitem中包含hitem再开启循环continueFlag = 0//breakval loop = new Breaksloop.breakable(//遍历hitems,如果oitems中包含hitem,则移除oitems中的这个item,并将continueFlag置为1;且如果这个item时hitems中的最后一个,则count+1//否则退出循环;for(hitem <- hitems){if (oitems.contains(hitem)){oitems.remove(oitems.indexOf(hitem))continueFlag=1if (hitem.equals(hitems.last)){count+=1}}else {loop.break()}})}//返回resultResult(row.getString(0), row.getString(1), row.getString(2), row.getString(3), count)})result.show()}
}

3.结果

笛卡尔积的结果:

计算后的结果:

spark:计算订单中所有商品是否属于套包相关推荐

  1. 127_Power PivotPower BI DAX计算订单商品在库时间(延伸订单仓储费用)

    博客:www.jiaopengzi.com 焦棚子的文章目录 请点击下载附件 一.背景 前面已经写过一个先进先出的库龄案例,在业务发生又有这样一个需求:先进先出前提,需要按照订单计算每个商品在库时间, ...

  2. c语言 计算订单总价

    计算订单总价 一个商品订单中包含若干种不同的商品,每个商品包含商口名,单价,个数,请实现 sum_order 函数,计算订单需支付的总价. 函数定义 double sum_order(ORDER *o ...

  3. 删除商品时,如何不影响订单里该商品相关的信息显示

    问题: 起初删除的商品只是让active字段标记为0,不在前端显示,实际还存在于数据库里. 相关的订单展示页,还会调用到被隐藏的商品信息.随着系统的使用,商品主表会越来越大,如何切实的删除过期商品,并 ...

  4. springBoot项目--平台控制商品订单中各商家打印机打印小票--终极版

    之前写过一个打印机的一段代码,由于之前的代码存在缺陷,现在我来做下补充: 直接上干货: @Scheduled(cron = "0/5 * * * * ?")public void ...

  5. python 计算订单量最多的店铺订货金额_Python数据分析实例-统计学在解决奶茶店问题中的应用...

    作为数据分析师,除了熟练各种分析工具外,更重要的是分析.解决问题的能力以及扎实的数学功底,尤其是统计学. 本文将用一个例子,一步一步展示1)分析问题的步骤,2)更具需求选择合适工具和数据获取,3)和统 ...

  6. 采购订单中的容差项目解释

    AN: Amount for item without order reference AN:没有订单的项目金额 When you activate the item amount check , t ...

  7. 电商系统中的商品模型的分析与设计

    前言 在电商系统中,商品模型至关重要,是整个电商的核心,下面通过一个简单的分析,设计一个基础的商品模型. 商品模型的演化 在以前,那时CMS很流行,最常见的模型是栏目-文章模型.于是做电商的时候,自然 ...

  8. Spark计算工具类

    Vector vectors.txt 1 2.3 4.5 3 3.1 5.6 4 3.2 7.8 处理vectors.txt文件RDD[String]->RDD[Vector] package ...

  9. spark 算子例子_10年大数据架构师,用一文带你玩转Spark计算框架,你能读懂吗?...

    首先明确一点:学计算框架主要就是学2部分: 1.资源调度 2.任务调度 写一个spark程序包含加载配置文件,创建上下文,创建RDD , 调用RDD的算子,用户在算子中自定义的函数 map端:狭窄的理 ...

最新文章

  1. nginx只允许域名访问,禁止ip访问
  2. go语言的channel特性
  3. e2fsck -y 故障_MC2-XWHM-Y
  4. 20万数据 sql 快还是 java快?_H2数据库学习(一)
  5. python中exit的作用_python __enter__ 与 __exit__的作用,以及与 with 语句的关系
  6. 多年前的树莓派 B+ 重新工作
  7. 图片不显示问题 图片url监测改变问题
  8. 程序员:如何写出杀手级简历
  9. oracle decode_ORACLE常见问题-100问(系列一)
  10. PostgreSQL中定时job执行(pgAgent)
  11. 帮助你在移动设备上生成倾斜控制(重力控制)的旋转效果jQuery插件 - lenticular.js...
  12. PHP使用weui,微信小程序WeUI引入
  13. 将list中的数据类型都变成int类型
  14. Linux(Ubuntu 14.04) 罗技(logitech) G29 游戏方向盘数据解析(支持自定义开发)
  15. win10资源管理器打开缓慢,自动搜索
  16. UnionPay-银联支付-netcore(一)
  17. echarts世界地图中英文转换
  18. CoreOS在儿童节发布了自己的分布式存储Torus
  19. 架构 - 关于三种编程范式
  20. 《微机原理第五版》期末知识总结(第五章---第七章)

热门文章

  1. JAVA API个各种方法
  2. 分享几个实用性爆棚的网站,快放进收藏夹里吃灰吧!(三)
  3. Istio 是啥?一文带你彻底了解
  4. 深入理解JVM—满足什么条件的对象才会进入老年代?
  5. LeetCode题目笔记--12.整数转罗马数字
  6. 2022第二届网刃杯网络安全大赛-Re
  7. EOS Contract 合约
  8. 每公里配速9分18秒,双足机器人完成5公里慢跑
  9. 网络游戏外挂制作技术浅谈
  10. 推荐系统中不得不学的对比学习(Contrastive Learning)方法