2016-05-13 7 views
0

現在、私はPigで作業しており、フィールド値(chararray)が別のフィールド(またはchararray)に存在するかどうかを確認しようとしています。 例を示します。Apache Pig - 他の文字列の部分文字列

ファイルt.txt:上記の例で

1;This is a banana which is yellow.;Fruit;Banana 
2;This is not about fruit but about Apple Inc.;Company;Apple 

は、私が最後のフィールド(すなわちBananaApple)は、第2フィールド(文)内に存在するかどうかを確認したいです。ここに私の豚のスクリプトはこれまでです:

a = LOAD 't.txt' using PigStorage(';') AS (id:chararray, sentence:chararray, kind:chararray, search:chararray); 

b = FOREACH a GENERATE id, LOWER(sentence) as sent:chararray, kind, LOWER(search) as srch:chararray; 

c = FILTER b BY sent MATCHES '.* srch .*'; 

私が達成しようとしている目標は、検索ワードを囲むバイグラムを取得することです。具体的な例を与えるために、これは私が(または別の形で)を探していますものです:

(1,Fruit,{(a, banana),(banana, which}) 
(2,Company,{(about, apple),(apple, inc.}) 

だから、私の質問は:私はからフィールド文に一致するようにスキーマからフィールド検索を使用する方法スキーマ?

+0

だから、t.txtからのkindと一致する文と、第2のスキーマの検索が欲しいですか?すべての単語を含む文を探したり、リストのいずれかのタプルから単語を1つだけ探したりすることです。 –

+0

例を挙げましょう:各行から、文(フィールド "sentence"に含まれる)から値(フィールド "search"に含まれています)を抽出します。これは、MATCHESを使用する状況と非常によく似ていますが、パターンはあります。しかし、パターンとして、ここでは、与えられたパターンの代わりにフィールド "検索"に含まれる値を使用したいと思います。つまり、パターンは動的であり、行ごとに変化します。 –

答えて

2

UDFを使用します。文章と検索項目をUDFに渡します。UDFでは、文章を単語に分割し、単語を繰り返します。単語が一致すると、検索項目の前後に単語が表示されます。

PigScript

REGISTER GetSurroundingWords.jar; 
DEFINE GetSurroundingWords com.mypackages.GetSurroundingWords(); 

A = LOAD 'test11.txt' using PigStorage(';') AS (id:chararray, sentence:chararray, kind:chararray, search:chararray); 
B = FOREACH A GENERATE id, LOWER(sentence) as sent:chararray, kind, LOWER(search) as srch:chararray; 
C = FOREACH B GENERATE id,kind,GetSurroundingWords(sent,srch); 
DUMP C; 

出力

Output

のJava UDF

package com.mypackages; 

import java.io.IOException; 
import org.apache.pig.EvalFunc; 
import org.apache.pig.data.Tuple; 

public class GetSurroundingWords extends EvalFunc<String> 
{ 
    public String exec(Tuple input) throws IOException 
    { 
     if(input != null && input.size() != 0) 
     { 
      String sInputString = input.toString(); 
      String sOutputString = ""; 
      try 
      { 
       if(sInputString != null && !sInputString.isEmpty()) 
       { 
        String [] sInputStringItems = sInputString.split(","); 
        String sSentence = sInputStringItems[0].replace('(', ' ').trim(); 
        String [] sWords = sSentence.split(" "); 
        String sSearchItem = sInputStringItems[1].replace(')',' ').trim(); 

        for(int iIndex = 0;iIndex < sWords.length;iIndex ++) 
        { 
         if(sWords[iIndex].equals(sSearchItem)) 
         { 
          try 
          { 
           sOutputString = "(" + sWords[--iIndex] + "," + sSearchItem + ")"; 
          }catch(Exception ex) 
          { 
           sOutputString = "(" + sSearchItem + ")"; 
          } 

          int iNextItem = iIndex + 2; 
          try 
          { 
           sOutputString = sOutputString + "," + "(" + sSearchItem + "," + sWords[iNextItem] + ")"; 
          }catch(Exception ex) 
          { 
           sOutputString = sOutputString + "," + "(" + sSearchItem + ")"; 
          } 
          return sOutputString; 
         } 
        }   
       } 
       else 
       { 
        return null; 
       } 
      } 
      catch(Exception ex) 
      { 
       return null; 
      } 
      return sOutputString; 
     } 
     else 
     { 
      return null; 
     } 
    } 
} 
+0

あなたのご協力ありがとうございます! –

+1

@RobinTrietsch Cool、Java UDF、特に文字列の連結など、マイナーコードの最適化を行う必要があるかもしれません。Javaの専門家ではありません –

+0

私はJavaの専門家ではありませんが、 。少なくとも私はあなたのおかげで出発点が固いです! –

関連する問題