Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 检索IP地理位置_Scala_Apache Spark - Fatal编程技术网

Scala 检索IP地理位置

Scala 检索IP地理位置,scala,apache-spark,Scala,Apache Spark,我有两个.CSV文件,其中一个包括IP地址: 76.83.179.64 76.83.179.64 187.42.62.209 89.142.219.5 另一个包括IP范围和国家名称,如下所示: ip_from| ip_to| country_name| |16777216|16777471|Australia| 到目前为止,我所做的工作如下: 加载数据:ip_from、ip_to和国家/地区名称 val rdd1 = sqlContext.read.format("csv"

我有两个.CSV文件,其中一个包括IP地址:

  • 76.83.179.64

  • 76.83.179.64

  • 187.42.62.209

  • 89.142.219.5

另一个包括IP范围和国家名称,如下所示:

 ip_from|  ip_to|  country_name|    

|16777216|16777471|Australia|
到目前为止,我所做的工作如下:

加载数据:ip_from、ip_to和国家/地区名称

val rdd1 = sqlContext.read.format("csv").option("inferSchema", 
"true").load("/FileStore/tables/locations.CSV")
val df2 = rdd1.toDF()
加载数据并将其从IP转换为Long

val rdd2 = sc.textFile("/FileStore/tables/ipaddress.csv")
def ipToLong(ipAddress: String): Long = {
ipAddress.split("\\.").reverse.zipWithIndex
.map(a=>a._1.toInt*math.pow(256,a._2).toLong).sum
}
val df1 = rdd2.map(x=>ipToLong(x)).toDF()

现在,我应该编写什么用户定义函数来加入DFs(或查找)并根据ip地址检索国家名称

对于您的情况,您只需使用以下逻辑

df1.join(df2, df1("value") >= df2("ip_from") && df1("value") <= df2("ip_to"), "left")

df1.join(df2,df1(“value”)>=df2(“ip_from”)和&df1(“value”)您可以使用
left_outer
与执行ip到long转换的
UDF
连接,如以下示例所示:

val dfIP = Seq(
  ("76.83.179.64"),
  ("76.83.179.64"),
  ("187.42.62.209"),
  ("89.142.219.5")
).toDF("ip")

val dfRange = Seq(
  (1000000000L, 1500000000L, "Country A"),
  (1500000000L, 3000000000L, "Country B"),
  (3000000000L, 4000000000L, "Country C")
).toDF("ip_from", "ip_to", "country_name")

def ipToLong = udf(
  (ip: String) =>
    ip.split("\\.").reverse.zipWithIndex.map(
      a => a._1.toInt * math.pow(256,a._2).toLong
    ).sum
)

val dfJoined = dfIP.join(
  dfIPRange,
  ipToLong($"ip") >= $"ip_from" && ipToLong($"ip") < $"ip_to",
  "left_outer"
)

dfJoined.show
+-------------+----------+----------+------------+
|           ip|   ip_from|     ip_to|country_name|
+-------------+----------+----------+------------+
| 76.83.179.64|1000000000|1500000000|   Country A|
| 76.83.179.64|1000000000|1500000000|   Country A|
|187.42.62.209|3000000000|4000000000|   Country C|
| 89.142.219.5|1500000000|3000000000|   Country B|
+-------------+----------+----------+------------+
val dfIP=Seq(
("76.83.179.64"),
("76.83.179.64"),
("187.42.62.209"),
("89.142.219.5")
).toDF(“ip”)
val dfRange=序列(
(1000000000L,150000000L,“A国”),
(150000000L,3000000000L,“B国”),
(30000000000L,4000000000L,“C国”)
).toDF(“ip_from”、“ip_to”、“country_name”)
def ipToLong=udf(
(ip:String)=>
ip.split(“\\”).reverse.zipWithIndex.map(
a=>a.\u 1.toInt*math.pow(256,a.\u 2).toLong
).sum
)
val dfjoin=dfIP.join(
德芬奇,
ipToLong($“ip”)>=$“ip_from”和&ipToLong($“ip”)<$“ip_to”,
“左外”
)
秀
+-------------+----------+----------+------------+
|ip | ip |从| ip |到|国家|名称|
+-------------+----------+----------+------------+
|76.83.179.64 | 100000000 | 150000000 |国家A|
|76.83.179.64 | 100000000 | 150000000 |国家A|
|187.42.62.209 | 30000000000 | 4000000000 | C国|
|89.142.219.5 | 150000000 | 3000000000 | B国|
+-------------+----------+----------+------------+

你应该加入,然后使用范围函数。我认为应该是&&@user3616059,我已经编辑了我的答案:)如果答案对你有帮助,你可以接受并向上投票:)