2012-03-28 8 views
46

tôi đã làm một cái gì đó như thế này để đếm số lượng hàng trong một bí danh trong PIG:PIG làm thế nào để đếm số hàng trong alias

logs = LOAD 'log' 
logs_w_one = foreach logs generate 1 as one; 
logs_group = group logs_w_one all; 
logs_count = foreach logs_group generate SUM(logs_w_one.one); 
dump logs_count; 

này có vẻ là quá kém hiệu quả. Hãy khai sáng cho tôi nếu có cách nào tốt hơn!

Trả lời

90

COUNT địa chỉ là một phần của lợn see the manual

LOGS= LOAD 'log'; 
LOGS_GROUP= GROUP LOGS ALL; 
LOG_COUNT = FOREACH LOGS_GROUP GENERATE COUNT(LOGS); 
+2

Có thể đếm số lượng hàng trong một bí danh mà không nhóm đầu tiên? – zzz

+2

Cùng một câu hỏi. Tôi đọc rằng 'GROUP x ALL' sẽ buộc một serialization trong đường ống với hậu quả có thể làm chậm. Đúng không? –

+0

Bạn phải nhóm trước khi đếm. Theo http://pig.apache.org/docs/r0.15.0/func.html#count: "COUNT yêu cầu câu lệnh GROUP ALL trước cho số lượng toàn cầu và câu lệnh GROUP BY cho số lượng nhóm". –

29

Hãy cẩn thận, với COUNT mục đầu tiên của bạn trong túi không phải là null. Khác bạn có thể sử dụng hàm COUNT_STAR để đếm tất cả các hàng.

29

Arnon Rotem-Gal-Oz đã trả lời câu hỏi này một lúc trước, nhưng tôi nghĩ một số có thể thích phiên bản ngắn gọn hơn này một chút.

LOGS = LOAD 'log'; 
LOG_COUNT = FOREACH (GROUP LOGS ALL) GENERATE COUNT(LOGS); 
0

Đây là phiên bản có tối ưu hóa. Tất cả các giải pháp trên sẽ yêu cầu lợn để đọc và viết tuple đầy đủ khi đếm, kịch bản này dưới đây chỉ cần viết '1'-s

DEFINE row_count(inBag, name) RETURNS result { 
    X = FOREACH $inBag generate 1; 
    $result = FOREACH (GROUP X ALL PARALLEL 1) GENERATE '$name', COUNT(X); 
}; 

Việc sử dụng nó như

xxx = row_count(rows, 'rows_count'); 
4

đếm cơ bản được thực hiện như được ghi trong câu trả lời khác, và trong tài liệu lợn:

logs = LOAD 'log'; 
all_logs_in_a_bag = GROUP logs ALL; 
log_count = FOREACH all_logs_in_a_bag GENERATE COUNT(logs); 
dump log_count 

Bạn có quyền đếm đó là không hiệu quả, thậm chí khi sử dụng COUNT địa chỉ BUILTIN lợn vì điều này sẽ u se một bộ giảm tốc. Tuy nhiên, tôi đã có một sự mặc khải ngày hôm nay rằng một trong những cách để tăng tốc nó sẽ là giảm việc sử dụng RAM của mối quan hệ chúng ta đang đếm.

Nói cách khác, khi đếm một mối quan hệ, chúng tôi không thực sự quan tâm đến dữ liệu, vì vậy hãy sử dụng ít RAM nhất có thể. Bạn đã đi đúng hướng với lần lặp đầu tiên của tập lệnh đếm.

logs = LOAD 'log' 
ones = FOREACH logs GENERATE 1 AS one:int; 
counter_group = GROUP ones ALL; 
log_count = FOREACH counter_group GENERATE COUNT(ones); 
dump log_count 

Điều này sẽ làm việc trên các mối quan hệ lớn hơn nhiều so với tập lệnh trước và sẽ nhanh hơn nhiều. Sự khác biệt chính giữa điều này và kịch bản gốc của bạn là chúng ta không cần phải tổng hợp bất cứ điều gì.

0

gì bạn muốn là để đếm tất cả các dòng trong một mối quan hệ (bộ dữ liệu trong Pig Latin)

này là rất dễ dàng làm theo các bước sau:

logs = LOAD 'log'; --relation called logs, using PigStorage with tab as field delimiter 
logs_grouped = GROUP logs ALL;--gives a relation with one row with logs as a bag 
number = FOREACH LOGS_GROUP GENERATE COUNT_STAR(logs);--show me the number 

tôi phải nói điều quan trọng là Trịnh Gia Dĩnh chỉ bằng cách sử dụng COUNT thay vì COUNT_STAR, chúng tôi sẽ chỉ có số dòng mà trường đầu tiên không phải là rỗng.

Ngoài ra tôi thích cú pháp một dòng của Jerome nó ngắn gọn hơn nhưng để trở thành giáo lý tôi thích chia nó thành hai và thêm một số nhận xét.

Nói chung tôi thích:

numerito = FOREACH (GROUP CARGADOS3 ALL) GENERATE COUNT_STAR(CARGADOS3); 

qua

name = GROUP CARGADOS3 ALL 
number = FOREACH name GENERATE COUNT_STAR(CARGADOS3); 
2

SỬ DỤNG COUNT_STAR

LOGS= LOAD 'log'; 
LOGS_GROUP= GROUP LOGS ALL; 
LOG_COUNT = FOREACH LOGS_GROUP GENERATE COUNT_STAR(LOGS);