一条快递单号 会经过多个分拨,每次在分拨都会至少做一次到件、发件。而发件的时候会指定下一站。如果多次发件,就要选择正确的下一站,如果没有正确的下一站,则取最后一次发件。
之前的难点是 不知道哪个站点 是 正确的下一站。
后来才理解过来, 为了判断 正确的下一站,首先要确定 经过了哪些站点。
只有得到了 经过的站点,才能得知 正确的下一站。
不然直接在route里判断无法得知 正确的下一站是谁了。
spark.udf.register("analyRoute", ( rec_site_id: Number, sign_site_id: Number, r1: Seq[GenericRowWithSchema]) => { /** * 经过的route对象,是一个数组 |-- route: array (nullable = true) * | |-- element: struct (containsNull = true) * | | |-- scan_date: timestamp (nullable = true) * | | |-- scan_site_id: decimal(19,0) (nullable = true) * | | |-- pre_or_next_station_id: decimal(19,0) (nullable = true) * | | |-- use_type: integer (nullable = true) * * use_type: * 1 发件 * 2 到件 */ val result = ListBuffer[ErrorData]() val recSiteId = rec_site_id.longValue() val signSiteId = sign_site_id.longValue() var index = 0 //这里 就是解析route,获得 经过了哪些站点 val passCenter = r1.foldLeft(List[(Long, Int)]())((l1: List[(Long, Int)], row: GenericRowWithSchema) => { val siteId = row.getAs[Number]("scan_site_id").longValue() if (l1.isEmpty) { List((siteId, 0)) } else { //如果此时的扫描的站点 和 上一次的扫描是同一个,则不插入,反之新增站点 if (l1.last == siteId) l1 else l1.:+(siteId, 0) } }).toArray def updateRoute(siteId: Long, useType: Int, useTime: Timestamp, nextSiteId: Long): Unit = { if (result.length == 0) { result.append(ErrorData(siteId).updateStatus(recSiteId, useType, useTime, nextSiteId, signSiteId)) } else { if (result(index).siteId == siteId) { result(index) = result(index).updateStatus(recSiteId, useType, useTime, nextSiteId, signSiteId) } else { val data1 = ErrorData(siteId) result.append(data1.updateStatus(recSiteId, useType, useTime, nextSiteId, signSiteId)) index += 1 } } } for (no1 <- 0 until (r1.length)) { val row = r1(no1) val siteId = row.getAs[Number]("scan_site_id").longValue() val useType = row.getAs[Int]("use_type") val useTime = row.getAs[Timestamp]("scan_date") val nextSiteId = row.getAs[Number]("pre_or_next_station_id").longValue() //如果是发件 if (useType == 1) { //同分拨多次发件 if (no1 + 1 < r1.length && r1(no1 + 1).getAs[Number]("scan_site_id").longValue() == siteId && r1(no1 + 1).getAs[Int]("use_type") == 1) { //如果此时 还没有站点正确的下一站 且 此时的下一站是正确的下一站 if (passCenter(index)._2 == 0 && index + 1 < passCenter.length && nextSiteId == passCenter(index + 1)._1) { //更新逻辑,告诉程序 这个站点的扫描 已经找到了 正确了下一站 passCenter(index) = (siteId, 1) //去更新逻辑 updateRoute(siteId, useType, useTime, nextSiteId) } } else if (passCenter(index)._2 == 0) { updateRoute(siteId, useType, useTime, nextSiteId) } } else { updateRoute(siteId, useType, useTime, nextSiteId) } } val resultLen = result.length val indexRs = ListBuffer[Int]() for (i <- 0 until resultLen) { if (result(i).siteId != signSiteId && result(i).nextSiteId > 0 && result(i).nextSiteId != signSiteId) { if (i < resultLen - 1 && result(i).nextSiteId != result(i + 1).siteId) { indexRs.append(i) } else if (i == resultLen - 1) { indexRs.append(i) } } } indexRs.foreach(index => { result.append(ErrorData(result(index).nextSiteId)) }) if (result.filter(_.siteId == recSiteId).isEmpty) { result.append(ErrorData(recSiteId, hasRec = true)) } if (result.filter(_.siteId == signSiteId).isEmpty) { result.append(ErrorData(signSiteId, hasSign = true)) } result })
本人已经有5年的大数据开发工作经验了,处理的都是 快递数据。
如果大家有意向 在 快递方面的大数据 或者 java开发 有所心动,可以 联系我进行内推。(qq:1729874221)