我正在尝试进行一些聚合,以便将指标发布到Cloud watch。我在保存最终结果之前添加了我的指标计数逻辑。基本上我正试图获得有价值的客户数量>每列0。这样我就可以得到数字和百分比。
case class ItemData(totalRent : Long, totalPurchase: Long, itemTypeCounts: Map[String, Int] ) extends Serializable
import scala.collection.JavaConversions._
class ItemDataMetrics(startDate: String) {
var totals: ItemData = _
def countNonZero(c: Long): Int = {if (c > 0) 1 else 0}
def accumulate(featureData: ItemData) {
totals.totalRent+= countNonZero( featureData.totalRent )
totals.totalPurchase += countNonZero( featureData.totalPurchase )
for (entry <- featureData.itemTypeCounts.entrySet) {
if (totals.itemTypeCounts.contains( entry.getKey )) {
totals.itemTypeCounts.updated( entry.getKey, entry.getValue + countNonZero( entry.getValue ) )
} else {
totals.itemTypeCounts.put( entry.getKey, countNonZero( entry.getValue ) )
}
}
}
}
var totalCustomer : Int = 0
val itemMetrics: ItemDataMetrics = new ItemDataMetrics(startDate)
val resultValue = resultDF.map( {
r => {
val customerId = r.getAs[String]( "customerId" )
val totalRent = r.getAs[Long]( "totalRent" )
val totalPurchase = r.getAs[Long]( "totalPurchase" )
val itemTypeCounts = r.getAs[Map[String, Int]]( "itemType" )
val items = ItemData( totalRent, totalPurchase, itemTypeCounts)
totalCustomer = totalCustomer + 1
itemMetrics.accumulate(items)
val jsonString = JacksonUtil.toJson( items)
(customerId, jsonString)
}
} )
publishMetrics(startDate, featureMetrics) ---- publishes metrics to cloud watch
resultValue.saveAsTextFile("S3:....")
但不断收到错误:
<console>:26: error: value += is not a member of Long
totals.totalRent += countNonZero( itemData.totalRent )
^
<console>:27: error: value += is not a member of Long
totals.totalPurchase += countNonZero( itemData.totalPurchase )
<console>:36: error: value entrySet is not a member of Map[String,Int]
for (entry <- itemData.itemTypeCounts.entrySet) {
我是scala / spark的新手。有人可以告诉我这里我做错了什么吗?
答案 0 :(得分:4)
在Scala中x += y
有效的条件有两个:
x
有一个名为+=
的方法,将以y
作为参数调用,或者x
是var
,其方法名为+
。在这种情况下,x
将被分配x + y
现在Long
只有+
方法,没有+=
方法。因此,如果+=
为Long
,您只能在var
上使用ItemData
。现在您没有显示totals.totalRent
类的定义,但由于您收到错误,我认为val
是def
(或+=
)。因此,它无法重新分配,您无法在其上使用{{1}}。
答案 1 :(得分:2)
在Scala中,+=
通常采用可变变量(var
),为其添加值,并将新值重新分配给变量。这只适用于var
,因为这是一个可变变量。它不适用于val
(不可变)或函数定义。
在下面一行中,totalRent
是val
,无法重新分配。
totals.totalRent+= countNonZero( featureData.totalRent )
您可以在案例类变量定义中使用var
而不是默认val
来解决此问题。见下文:
case class ItemData(var totalRent : Long, var totalPurchase: Long, var itemTypeCounts: Map[String, Int] ) extends Serializable
这将允许+=
重新分配。