2016-10-17 3 views
1

Ich versuche, einige Aggregate für die Veröffentlichung von Metriken zu Cloud Watch zu tun. Ich füge meine Metrik-Zähllogik hinzu, bevor ich das Endergebnis speichere. Grundsätzlich versuche ich die Anzahl der Kunden mit Wert> 0 für jede Spalte zu ermitteln. Damit ich Nummer und Prozentsatz bekommen kann.Fehler: Wert + = ist kein Mitglied von Long Scala

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:....") 

Aber immer Fehler halten:

<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) { 

Ich bin neu in scala/Funken. Können mir einige sagen, was ich hier falsch mache?

Antwort

3

Es gibt zwei Bedingungen, unter denen x += y gültig in Scala ist:

  1. x ein Verfahren += genannt hat, die mit y als Argument aufgerufen wird, oder
  2. x ist ein var und hat ein Methode namens +. In diesem Fall x wird das Ergebnis der x + y

Long nur jetzt zugeordnet werden hat eine + Methode, kein += Verfahren. Daher können Sie += nur auf einem verwenden, wenn es ein var ist. Jetzt haben Sie die Definition der Klasse ItemData nicht angezeigt, aber da Sie einen Fehler erhalten haben, gehe ich davon aus, dass totals.totalRent ein val (oder ein def) ist. Daher kann es nicht neu zugewiesen werden und Sie können += nicht darauf verwenden.

+0

Mit ItemData aktualisiert. Kann ich das irgendwie machen? – Newbie

+0

@Newbie Sie können 'totalRent' und' totalPurchases' 'var's machen, aber vielleicht möchten Sie Ihren gesamten Ansatz ändern, um überhaupt keine Mutation zu benötigen. – sepp2k

2

In Scala nimmt += im Allgemeinen eine veränderbare Variable (var), fügt einen Wert hinzu und weist den neuen Wert der Variablen neu zu. Dies funktioniert nur mit var, da dies eine veränderbare Variable ist. Es funktioniert nicht mit val (unveränderlich) oder mit einer Funktionsdefinition.

In der Zeile unten ist totalRent ein val und Neuzuweisung kann nicht stattfinden.

totals.totalRent+= countNonZero(featureData.totalRent) 

Sie können dieses Problem beheben, indem var in Ihrem Fall Klassenvariable Definitionen anstelle des Standard val verwenden. Siehe unten:

case class ItemData(var totalRent : Long, var totalPurchase: Long, var itemTypeCounts: Map[String, Int]) extends Serializable 

Dies ermöglicht es der += Neuzuordnung stattfinden.

+0

Gibt es einen Weg, dies zu tun? – Newbie

+0

Ich habe var für insgesamt verwendet. Ist es falsch ? – Newbie

+0

Ich habe das oben mit einer vorgeschlagenen Lösung aktualisiert. In Ihrer ItemData-Klasse können Sie die Felder totalRent, totalPurchase und itemTypeCounts als vars festlegen. –

Verwandte Themen