我有一个关于在1000万长度的spark RDD(或scala Array)中进行部分字符串匹配的最有效方法的问题。请考虑以下事项:
val set1 = Array("star wars", "ipad") //These are the String I am looking for
val set2 = RDD[("user1", "star wars 7 is coming out"),
("user1", "where to watch star wars"),
("user2", "star wars"),
("user2", "cheap ipad")]
我希望能够计算Set1中属于Set1的每个字符串的出现次数。所以结果应该是这样的:
Result = ("star wars", 3),("ipad", 1)
我还想计算搜索该术语的用户数(即不同的用户),因此结果应为:
Result = ("star wars", 2), ("ipad", 1)
我尝试了两种方法,第一种方法是将RDD字符串转换为set,flatMapValues然后进行连接操作,但它耗费内存。我正在考虑的另一种方法是正则表达式方法,因为只需要计数并给出确切的字符串,但我不知道如何使其有效(通过创建函数并在映射RDD时调用它?)
我似乎能够在使用LIKE的pgsql中轻松地完成此操作,但不确定是否存在以相同方式工作的RDD连接。
非常感谢任何帮助。
答案 0 :(得分:5)
正如Yijie Shen建议你可以使用正则表达式:
val regex = set1.mkString("(", "|", ")").r
val results = rdd.flatMap {
case (user, str) => regex.findAllIn(str).map(user -> _)
}
val count = results.map(_._2).countByValue()
val byUser = results.distinct().map(_._2).countByValue()