2017-08-22 11 views
1

私はScalaでSQLクエリを書き直そうとしています。私の条件に合った行をScalaで分ける方法は?

  1. ファイルはパイプで区切られています。
  2. フィールドMessageは、ファイルの4番目の列にあります。
  3. msgのクエリがCSV(MESSAGE >>>)のMessageの3列目にあります。

サンプルファイルのデータ:

[06-26 00:01:52,036] | Container : 5 | INFO | relation ID: 00002ZaaaaaaXdsZb:-1:55609051-1879-4be8-b1c9-1d2006b17135, Message: acadeontroller.java recordLogRequest - 50 (...)  , MESSAGE >>> API - XX_XX_XX {CHECKSUM=9ABF5975467E394F54442FBD4F6473D3,MEMBER_TYPE=} 

問合せは、下記のようになります。

 
INSERT OVERWRITE TABLE staging.cleaned_data_7 
SELECT * FROM staging.cleaned_data_6 
WHERE msg NOT LIKE '%KEEP_ALIVE%' 
AND msg NOT LIKE '%XXX_CHANNEL_SERVICE%' 
AND msg NOT LIKE '%XXX Finished%' 
AND msg NOT LIKE '%API -%' 
; 

私は二つの方法を試してみました。最初の方法は、mapfilterを使用することです。これは、大文字小文字に一致するレコード全体を抽出できません。私はフィールドのみを抽出できます。そのSELECT *クエリ以来、私はこれを使用することはできません。

val sample = sc.textFile("file:////home/user/sample.txt").map(x=>x.split('|')(3)).map(x=>x.split(',')(2)) 
val myFilter = sample.filter(x => 
    !(x contains "KEEP_ALIVE") && 
    !(x contains "XXX_CHANNEL_SERVICE") && 
    !(x contains "XXX Finished") && 
    !(x contains "API -")) 

方法2:私はpartition機能を使用しています。しかし、私はエラーに直面している。

val (valid,invalid) = readFile.partition{ line=> 
    val Message = line.split('|')(3).split(',')(2).toString 

    Message.filter(x => 
    !(x contains "KEEP_ALIVE") && 
    !(x contains "XXX_CHANNEL_SERVICE") && 
    !(x contains "XXX Finished") && 
    !(x contains "API -") 
) 
} 

<console>:48: error: value contains is not a member of Char 

答えて

1

は、フィルタ内のスプリットをやって試してみてください、次のように:この文の後

val skippedMessages = List("KEEP_ALIVE", "XXX_CHANNEL_SERVICE", "XXX Finished", "API -") 
val result = sample.filter { line => 
    val message = line.split('|')(3).split(',')(2) 
    !skippedMessages.exists(message.contains) 
} 
1

val message = line.split('|')(3).split(',')(2).toString、変数messageStringです。

Stringfilter()と入力すると、個別のChar要素が抽出され、フィルタリングする場合は、Charを残し、除外する項目は除外します。

また、partition()メソッドはBoolean結果を必要としますが、filter()は供給されません。

これを試してみてください。

val (valid,invalid) = readFile.partition{ line=> 
    val message = line.split('|')(3).split(',')(2).toString 

    !(message contains "KEEP_ALIVE") && 
    !(message contains "XXX_CHANNEL_SERVICE") && 
    !(message contains "XXX Finished") && 
    !(message contains "API -") 
} 
関連する問題