2012-03-28 6 views
46

में पंक्तियों की एक संख्या की गणना करना मैं सुअर में एक उपनाम में पंक्तियों की संख्या गिनती करने के लिए कुछ इस तरह किया:सुअर कैसे उर्फ ​​

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; 

यह भी अक्षम हो रहा है। यदि कोई बेहतर तरीका है तो कृपया मुझे प्रबुद्ध करें!

उत्तर

90

COUNT सुअर see the manual का हिस्सा

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

पहले समूह में बिना किसी अन्य नाम में पंक्तियों की संख्या गिनती करने के लिए यह संभव है? – zzz

+2

वही प्रश्न। मैंने पढ़ा है कि 'ग्रुप एक्स ऑल' पाइपलाइन में एक क्रमिकरण को संभावित रूप से धीमा कर देगा। क्या वो सही है? –

+0

आपको गिनने से पहले समूह करना होगा। Http://pig.apache.org/docs/r0.15.0/func.html#count के अनुसार: "COUNT को वैश्विक गणनाओं और समूह गणनाओं के लिए ग्रुप बाय स्टेटमेंट के लिए पिछले समूह के सभी विवरणों की आवश्यकता है।" –

29

सावधान रहें, बैग में COUNT अपना पहला आइटम के साथ रिक्त नहीं हो जाना चाहिए। अन्यथा आप सभी पंक्तियों को गिनने के लिए फ़ंक्शन COUNT_STAR का उपयोग कर सकते हैं।

29

अरोन रोटेम-गैल-ओज़ ने कुछ समय पहले ही इस प्रश्न का उत्तर दिया था, लेकिन मैंने सोचा कि कुछ इसे थोड़ा और संक्षिप्त संस्करण पसंद कर सकते हैं।

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

यहां अनुकूलन वाला एक संस्करण है। उपरोक्त सभी समाधान पढ़ सकते हैं और पूर्ण टपल जब गिनती लिखने के लिए सुअर की आवश्यकता होगी, नीचे इस स्क्रिप्ट सिर्फ लिखना '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); 
}; 

यह

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

बेसिक गिनती की तरह उपयोग के रूप में किया जाता है अन्य उत्तर में कहा गया था, और सुअर दस्तावेज में:

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 

आप कर रहे हैं सही है कि उनकी गिनती भी सुअर के builtin COUNT का उपयोग करते समय, क्योंकि इस यू होगा, अक्षम है एक reducer से। हालांकि, आज मेरे पास एक रहस्योद्घाटन था कि इसे गति देने के तरीकों में से एक उस संबंध के राम उपयोग को कम करना होगा जिसे हम गिन रहे हैं।

दूसरे शब्दों में, जब संबंधों की गिनती करते हैं, तो हम वास्तव में डेटा के बारे में परवाह नहीं करते हैं, इसलिए जितना संभव हो उतना कम रैम का उपयोग करें। आप गिनती स्क्रिप्ट के अपने पहले पुनरावृत्ति के साथ सही रास्ते पर थे।

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 

यह पिछले लिपि की तुलना में बहुत बड़े संबंधों पर काम करेगा और बहुत तेज होना चाहिए। इस और आपकी मूल लिपि के बीच मुख्य अंतर यह है कि हमें कुछ भी करने की आवश्यकता नहीं है।

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 

मेरे पास है यह महत्वपूर्ण है केविन के कहने के लिए:

0

क्या आप चाहते हैं एक संबंध में सभी लाइनों (पिग लैटिन में डाटासेट)

यह बहुत आसान अगले चरणों का पीछा कर रहा है गिनती करने के लिए है COUNT_STAR के बजाय COUNT का उपयोग करने के रूप में इंगित करें, हमारे पास केवल उन पंक्तियों की संख्या होगी जो पहले फ़ील्ड शून्य नहीं हैं।

मुझे जेरोम की एक पंक्ति वाक्यविन्यास पसंद है, यह अधिक संक्षिप्त है लेकिन व्यावहारिक होने के लिए मैं इसे दो में विभाजित करना और कुछ टिप्पणी जोड़ना पसंद करता हूं।

सामान्य तौर पर मैं पसंद करते हैं:

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

से अधिक
name = GROUP CARGADOS3 ALL 
number = FOREACH name GENERATE COUNT_STAR(CARGADOS3); 
2

उपयोग COUNT_STAR

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