web-dev-qa-db-de.com

PIG, wie eine Anzahl von Zeilen in Alias ​​gezählt wird

Ich habe so etwas gemacht, um die Anzahl der Zeilen in einem Alias ​​in PIG zu zählen:

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;

Dies scheint zu ineffizient zu sein. Bitte kläre mich auf, wenn es einen besseren Weg gibt! 

48
kee

COUNT ist Teil von pig siehe Handbuch

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

Arnon Rotem-Gal-Oz hat diese Frage bereits vor einiger Zeit beantwortet, aber ich dachte, einige mögen diese etwas knappere Version.

LOGS = LOAD 'log';
LOG_COUNT = FOREACH (GROUP LOGS ALL) GENERATE COUNT(LOGS);
29
Jerome Serrano

Seien Sie vorsichtig, mit COUNT darf Ihr erster Artikel in der Tasche nicht null sein. Andernfalls können Sie die Funktion COUNT_STAR verwenden, um alle Zeilen zu zählen.

29
Kevin

Die Grundzählung erfolgt wie in anderen Antworten und in der Schweinedokumentation angegeben:

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

Sie haben Recht, dass das Zählen ineffizient ist, selbst wenn der eingebaute COUNT von pig verwendet wird, da hier nur ein Reduzierer benötigt wird. Ich hatte jedoch heute eine Offenbarung, dass eine der Möglichkeiten zur Beschleunigung darin besteht, die Verwendung von RAM der Beziehung, die wir zählen, zu reduzieren.

Mit anderen Worten: Wenn wir eine Beziehung zählen, kümmern wir uns nicht wirklich um die Daten selbst, also verwenden wir so wenig RAM wie möglich. Sie waren mit Ihrer ersten Iteration des Count-Skripts auf dem richtigen Weg.

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

Dies funktioniert mit viel größeren Beziehungen als das vorherige Skript und sollte viel schneller sein. Der Hauptunterschied zwischen diesem und Ihrem ursprünglichen Skript besteht darin, dass wir nichts summieren müssen.

4
WattsInABox

USE COUNT_STAR

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

Sie möchten alle Zeilen in einer Beziehung zählen (Datensatz in Pig Latin)

Dies ist sehr einfach, wenn Sie die nächsten Schritte ausführen:

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

Ich muss sagen, dass es wichtig ist, dass Kevin COUNT anstelle von COUNT_STAR verwendet. Wir haben nur die Anzahl der Zeilen, deren erstes Feld nicht Null ist.

Ich mag auch die einzeilige Syntax von Jerome, sie ist prägnanter, aber um didaktisch zu sein, ziehe ich es vor, sie in zwei Teile zu teilen und etwas Kommentar hinzuzufügen.

Im Allgemeinen bevorzuge ich:

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

Über

name = GROUP CARGADOS3 ALL
number = FOREACH name GENERATE COUNT_STAR(CARGADOS3);
0
Javier Bañez

Hier ist eine Version mit Optimierung. Alle oben genannten Lösungen erfordern, dass pig beim Zählen volles Tupel lesen und schreiben kann. In diesem Skript werden '1'-s geschrieben

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

Die benutzen es gerne

xxx = row_count(rows, 'rows_count');
0
Igor Katkov