【问题标题】:To get sum of certain value from resultset in riak从 riak 的结果集中获取某个值的总和
【发布时间】:2014-06-06 04:40:54
【问题描述】:

我正在开发 riak-java 客户端。在做 Mapreduce 时,我得到了以下输出。 现在我想从我得到的结果集中获取 ticketValue 的总和。我想通过传递 userID 来获取它。

更新

从这个方法我得到如下结果集

 def fetchTicketValue(userID:String): Boolean = {
    try{
      val result = riakClient.mapReduce("table-ticket","userID:Kim")
      .addMapPhase(new NamedJSFunction("Riak.mapValuesJson"),true)
      .execute
      val o:String = result.getResultRaw
    }catch{
      case e : Exception => 
         e.printStackTrace
     }
     true
  }

我之前忘了提到大括号[{....},{....},{....}]

[{"ticketValue":3,"userID":"Kim","Date":"date","ticketID":"98394kjdf","ticketSource":"reg"},{"ticketValue":3,"userID":"Kim","Date":"date","ticketID":"98394kjdf","ticketSource":"reg"},{"ticketValue":3,"userID":"Kim","Date":"date","ticketID":"98394kjdf","ticketSource":"reg"}]

LIKE: userID:"kim"

RESULT: ticketValue:9

如何获取数据?任何想法都将受到高度赞赏。 提前致谢。

(Riak 版本:1.3.2 和 Riak Java 客户端:1.1.4)

【问题讨论】:

  • 您想在 Scala 中还是在 reduce 阶段计算总和?
  • (我不知道 Riak。)结果是否像您在上面写的那样作为裸字符串返回?
  • 让我用 SQL 的例子来解释一下。上面的字符串与查询的结果相同Select * from table_name where userID="Kim"
  • @Joe 是的,我想计算 scala 中的总和。我的要求是,当我在 fetch 之后得到一个 resultset 时,我需要总结票证价值。正如上面给定的行,它就像 SQL 的数据表,我想像我们在 SQL 中做的 sum(ticketvalue) 一样 总结票据价值。希望你能理解我的逻辑。

标签: scala riak


【解决方案1】:

你看过 Jerkson 库(据我所知,它已被废弃,但仍提供良好的功能),它是用于 java 的 Jackson 库的 scala 包装器,使用默认的 Play JSON 库是一个好主意,但自从它从 2.11 开始弃用。以后,Jerkson 也容易多了。

使用 Jerkson 你可以试试这个,代码是不言自明的,我最近遇到了同样的问题Link->

var sum:Int = 0
val parsedList = parse[List[Ticket]](result.getResultRaw)
for (e <-parsedList){
  sum = sum + e.ticketValue
}
println("Final sum: "+sum)

【讨论】:

    【解决方案2】:
    import scala.util.parsing.json.JSON
    
    case class Row(ticketValue: Int, userId: String, date: String, ticketId: String, ticketSource: String)
    
    // I'm sure there's a way to do this more cleanly; using it as an implicit maybe
    def mapToRow(m: Any): Row = {
      val typedM = m.asInstanceOf[Map[String, Any]]
      Row(typedM("ticketValue").asInstanceOf[Double].toInt,
        typedM("userID").toString,
        typedM("Date").toString,
        typedM("ticketID").toString,
        typedM("ticketSource").toString)
    }
    
    def getSum(result: String, userId: String) = {
        val rows = JSON.parseFull("[" + result + "]").get.asInstanceOf[Seq[Map[String, Any]]].map(mapToRow)
        rows.filter(_.userId == userId).map(_.ticketValue).sum
    }
    
    
    val result = """{"ticketValue":3,"userID":"Samy","Date":"date","ticketID":"98394kjdf","ticketSource":"reg"},{"ticketValue":3,"userID":"Kim","Date":"date","ticketID":"98394kjdf","ticketSource":"reg"},{"ticketValue":3,"userID":"Kim","Date":"date","ticketID":"98394kjdf","ticketSource":"reg"},{"ticketValue":3,"userID":"Kim","Date":"date","ticketID":"98394kjdf","ticketSource":"reg"}"""
    getSum(result, "Kim")
    

    【讨论】:

    • 您的答案的输出与我需要的相同,但我提供的 String 不是裸字符串,它是 datatable,如sql。根据您在 mapToRow 中的回答,当我在控制台中打印 m 的值时,我会在每次迭代中分别获得 Map(...) 但在我的如果我在一次迭代中得到 List(Map(...),Map(...),(...)) 。为了更好地理解,我更新了我的问题。很抱歉给您带来不便,我对编程和博客也是新手。谢谢。
    • @Uraniium 您可以像这样从地图列表中制作地图:m.reduce(_ ++ _)
    • 能否请您向我解释一下如何使用m.reduce(_ ++ _)
    • @Uraniium 您需要在拥有List(Map(…), Map(…), …) 的地方使用它才能获得Map(…)。它基本上会合并ListMaps。 — 您还需要将 Map[String, Any] 更改为 List[Map[…]],具体取决于结果列表的外观。
    猜你喜欢
    • 2019-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-11
    • 2019-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多