前回の記事の私の使用は、テストデータは、いくつかの国内の自治体または不正確な、と香港が非友好的である中国のショー、ではないことが判明し、無料のプラグインのライブラリーは、水滴開発maxmind。
これは非常に良いですip2region発行され、ビットを探しています。https://github.com/lionsoul2014/ip2region
私は、ライブラリを使用して、前のコードを使用して、わずかに変更され、テストも、効果が良いです。基本的には値が再び空にしません。
著者が言ったように、クエリの効率について、私がテストし、最速のは本当ですが、やや少ない特定のストリームの先頭いくつかのバッチ効率の火花があるでしょう、そしてゆっくりと持ち上げmemsearch
パッケージcom.student インポートio.github.interestinglab.waterdrop.apis.BaseFilterの インポートcom.typesafe.configを{構成、ConfigFactory} インポートorg.apache.spark.SparkFilesの インポートorg.apache.spark.sql。{データセット、行を、 SparkSession} インポートorg.apache.spark.sql.functions。{COL、UDF} インポートscala.collection.JavaConversions._の インポートorg.lionsoul.ip2region.DbConfig インポートorg.lionsoul.ip2region.DbSearcherの インポートscala.collection.JavaConversions._ 輸入org.lionsoul.ip2region.DbConfigの インポートorg.lionsoul.ip2region.DbSearcher オブジェクトSearcherWrapper延びシリアライズ{ @ 過渡怠惰ヴァルサーチャー= { valを設定 = 新しいDBCONFIG ヴァルDBFILE = SparkFiles.get( "ip2region.db" ) ヴァルサーチャー = 新しいDbSearcher(設定、DBFILE) サーチャー } } クラス IP2Region2が延びBaseFilter { 構成:VARの設定を = ConfigFactory.empty() / ** *構成の設定。 * * / オーバーライドDEF setConfig(設定:構成):単位 = { 本の.config =設定 } / ** *コンフィグを取得します。 * * / 構成:GETCONFIG()DEFオーバーライド = { 本の.config } checkConfig DEFオーバーライド():(ブール、文字列) = { ヴァルrequiredOptions =リスト( "source_field" ) ヴァルnonExistsOptions:リスト[(文字列、ブール値)] = requiredOptions.map {オプション名=> (オプション名、config.hasPath(オプション名)) } .filter {P => !p._2 } もし(nonExistsOptions.length == 0 ){ (真、 "" ) }そうでない{ (偽、 "非空の文字列として設定指定してください" ) } } オーバーライドデフ(スパーク:SparkSessionを):準備単位 = { valのdefaultConfig = ConfigFactory.parseMap( 地図( "source_field" - > "raw_message" 、 「target_field " - > "__ROOT__" ) ) コンフィグ = config.withFallback(defaultConfig) } プロセスDEFオーバーライド(スパーク:SparkSession、DF:データセット[行]):データセット[行] = { ヴァルsrcField = config.getString(" source_field」) ヴァルip2region = UDF {IP:文字列=> ip2Location2(IP)} インポート org.apache.spark.sql.functions.split df.withColumn( "__region__" 、ip2region(COL(srcField))) .withColumn( "__country__"、スプリット(COL( "__地域__")、 "\\ |")(0 )) .withColumn( "__province __"、スプリット(COL( "__地域__")、 "\\ |")(2 )) .withColumn(「__city__ 」スプリット(COL( "__領域__")、 "\\ |")(3 )) .withColumn( "__isp __"、スプリット(COL( "__領域__")、 "\\ |")(4 )) } DEF ip2Location2 (IP:文字列) = { 試み{ valを探索= SearcherWrapper.searcher ヴァル応答 = searcher.memorySearch(IP) response.getRegion } キャッチ{ ケース EX:例外=> // ex.printStackTrace() "" } } }