2010-03-29 12 views
6

Bir günlük dosyasındaki satırları ayrıştırmak ve bilgiyi tekrar işleme döndürmek için Java'da yazılmış bir Kullanıcı Tanımlı İşlev (UDF) var, bu yüzden tüm işlemleri yapabilir.Bir EvalFunc domuzunda bir istisna atmak UDF sadece bu çizgiyi atlayabilir veya tamamen durdurabilir mi?

Bu şuna benzer:

public abstract class Foo extends EvalFunc<Tuple> { 
    public Foo() { 
     super(); 
    } 

    public Tuple exec(Tuple input) throws IOException { 
     try { 
      // do stuff with input 
     } catch (Exception e) { 
      throw WrappedIOException.wrap("Error with line", e); 
     } 
    } 
} 

Sorum şu: o IOException atarsa, tamamen duracaktır veya bir özel durum yoktur çizgilerin kalanı için sonuçlar döndürür ?

Örnek:

1.5 7 "Valid Line" 
1.3 gghyhtt Inv"alid line"" I throw an exceptioN!! 
1.8 10 "Valid Line 2" 

o iki satır işleyecek ve 'günlükleri' 2 dizilerini olacak yoksa sadece ölecek: Bu giriş sayesinde domuz

REGISTER myjar.jar 
DEFINE Extractor com.namespace.Extractor(); 

logs = LOAD '$IN' USING TextLoader AS (line: chararray); 
events = FOREACH logs GENERATE FLATTEN(Extractor(line)); 

bu çalıştırmak bir ateş?

cevap

8

İstisna UDF tarafından atılırsa, görev başarısız olur ve yeniden denenir.

Üç kez daha başarısız olur (varsayılan olarak 4 deneme) ve tüm iş başarısız olur.

hatayı günlüğe ve bir boş dönebilirsiniz durdurdu İşi olmasını istemiyoruz isterseniz:

public Tuple exec(Tuple input) throws IOException { 
    try { 
     // do stuff with input 
    } catch (Exception e) { 
     System.err.println("Error with ..."); 
     return null; 
    } 
} 

Ve Pig bunları daha sonra filtre:

events_all = FOREACH logs GENERATE Extractor(line) AS line; 
events_valid = FILTER events_all by line IS NOT null; 
events = FOREACH events_valid GENERATE FLATTEN(line); 

sizin örnekte çıktı sadece iki geçerli satıra sahip olacaktır (ancak hata sadece günlüklerde mevcut olduğundan ve işinizi kaybetmeyeceğiniz için bu davranışa dikkat edin!).

Cevap 1. Yorum yapmak:

Aslında, tüm çıkan tuple (şimdiye içeride hiçbir alanlar yoktur) boş olurdu. Örneğin

şema 3 alanları varsa:

events_all = FOREACH logs 
       GENERATE Extractor(line) AS line:tuple(a:int,b:int,c:int); 

ve bazı hatlar biz alacağı yanlıştır:

() 
((1,2,3)) 
((1,2,3)) 
() 
((1,2,3)) 

Ve boş satır filtre ve erişim deneyin yoksa benim durumumda

events = FOREACH events_all GENERATE line.a; 
+0

: bir alan bir java.lang.NullPointerException olsun Ayrıca, UDF'de bir şema tanımladım, bu yüzden null döndürerek, sonuçta ortaya çıkan tupledaki her şey null, doğru mu? –

+0

Bunu nasıl filtrelersiniz? FILTER olayları IS NOT NULL tarafından, EvalFunc her zaman 'a' anlayamazsa null döndürür varsayarak? –

+0

UDF tarafından döndürülen alanın adını filtrelemeniz gerekiyor. Bizim örneğimizde adı 'satır' ve değerleri 'boş' veya '(1,2,3)' olabilir. Yani ilk Domuz örneğinde gösterildiği gibi bir 'FILTER olayı satır NEDEN DEĞİL' yaparsınız. Üç boş alana sahip bir tuple döndürüyorsanız, ör. '(,,)' 'null' yerine 'FILTER event'lerinizi line.a IS NULL' yapamazsınız ancak daha az basittir. – Romain

İlgili konular