2012-03-17 8 views
13

Tôi đang xử lý dữ liệu từ tập hợp các tệp có chứa dấu ngày như một phần của tên tệp. Dữ liệu trong tệp không chứa dấu ngày tháng. Tôi muốn xử lý tên tệp và thêm nó vào một trong các cấu trúc dữ liệu bên trong tập lệnh. Có cách nào để làm điều đó trong Pig Latin (một phần mở rộng để PigStorage có thể?) Hoặc tôi cần phải preprocess tất cả các tập tin bằng cách sử dụng Perl hoặc tương tự trước?Làm cách nào để kết hợp tên tệp nhập hiện tại vào tập lệnh Pig Latin của tôi?

tôi hình dung một cái gì đó như sau:

-- Load two fields from file, then generate a third from the filename 
rawdata = LOAD '/directory/of/files/' USING PigStorage AS (field1:chararray, field2:int, field3:filename); 

-- Reformat the filename into a datestamp 
annotated = FOREACH rawdata GENERATE 
    REGEX_EXTRACT(field3,'*-(20\d{6})-*',1) AS datestamp, 
    field1, field2; 

Lưu ý đặc biệt "filename" datatype trong báo cáo LOAD. Có vẻ như nó sẽ phải xảy ra ở đó khi dữ liệu đã được tải quá muộn để quay lại tên tệp nguồn.

Trả lời

13

Người tuổi Hợi wiki như một ví dụ về PigStorageWithInputPath trong đó có các tên tập tin trong một lĩnh vực chararray thêm:

Ví dụ

A = load '/directory/of/files/*' using PigStorageWithInputPath() 
    as (field1:chararray, field2:int, field3:chararray); 

UDF

// Note that there are several versions of Path and FileSplit. These are intended: 
import org.apache.hadoop.fs.Path; 
import org.apache.hadoop.mapreduce.RecordReader; 
import org.apache.hadoop.mapreduce.lib.input.FileSplit; 
import org.apache.pig.backend.hadoop.executionengine.mapReduceLayer.PigSplit; 
import org.apache.pig.builtin.PigStorage; 
import org.apache.pig.data.Tuple; 

public class PigStorageWithInputPath extends PigStorage { 
    Path path = null; 

    @Override 
    public void prepareToRead(RecordReader reader, PigSplit split) { 
     super.prepareToRead(reader, split); 
     path = ((FileSplit)split.getWrappedSplit()).getPath(); 
    } 

    @Override 
    public Tuple getNext() throws IOException { 
     Tuple myTuple = super.getNext(); 
     if (myTuple != null) 
      myTuple.append(path.toString()); 
     return myTuple; 
    } 
} 
1

Một cách để làm điều này trong Bash và PigLatin có thể được tìm thấy tại: How Can I Load Every File In a Folder Using PIG?.

Những gì tôi đã làm gần đây mặc dù, và tìm thấy được nhiều sạch hơn là nhúng Pig trong Python. Điều đó cho phép bạn ném tất cả các loại biến và như vậy giữa hai. Một ví dụ đơn giản là:

#!/path/to/jython.jar          

# explicitly import Pig class                   
from org.apache.pig.scripting import Pig 

# COMPILE: compile method returns a Pig object that represents the pipeline       
P = Pig.compile(
       "a = load '$in'; store a into '$out';") 

input = '/path/to/some/file.txt' 
output = '/path/to/some/output/on/hdfs' 

# BIND and RUN                       
results = P.bind({'in':input, 'out':output}).runSingle() 

if results.isSuccessful() : 
    print 'Pig job succeeded' 
else : 
    raise 'Pig job failed' 

Hãy xem Julien Le Dem's great slides làm giới thiệu về điều này, nếu bạn quan tâm. Ngoài ra còn có một tấn tài liệu tại http://pig.apache.org/docs/r0.9.2/cont.pdf.

3

-tagSource không được dùng nữa trong Pig 0.12.0. Thay vào đó, hãy sử dụng

-tagFile - Gắn thêm tên tệp nguồn đầu vào vào đầu mỗi bộ.
-tagPath - Nối đường dẫn tệp nguồn đầu vào vào đầu mỗi tuple.

A = LOAD '/user/myFile.TXT' using PigStorage(',','-tagPath'); 
DUMP A ; 

sẽ cung cấp cho bạn đường dẫn tập tin đầy đủ như cột đầu tiên

(hdfs://myserver/user/blo/input/2015.TXT,439,43,05,4,NAVI,PO,P&C,P&CR,UC,40) 

refrence: http://pig.apache.org/docs/r0.12.0/api/org/apache/pig/builtin/PigStorage.html