web-dev-qa-db-fra.com

PIG comment compter un nombre de lignes dans un alias

J'ai fait quelque chose comme ça pour compter le nombre de lignes d'un alias dans PIG:

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;

Cela semble être trop inefficace. S'il vous plaît, éclairez-moi s'il y a un meilleur moyen! 

48
kee

COUNT fait partie de porc voir le manuel

LOGS= LOAD 'log';
LOGS_GROUP= GROUP LOGS ALL;
LOG_COUNT = FOREACH LOGS_GROUP GENERATE COUNT(LOGS);
94
Arnon Rotem-Gal-Oz

Arnon Rotem-Gal-Oz a déjà répondu à cette question il y a un moment, mais j'ai pensé que certains aimeraient cette version un peu plus concise.

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

Attention, avec COUNT votre premier article dans le sac ne doit pas être nul. Sinon, vous pouvez utiliser la fonction COUNT_STAR pour compter toutes les lignes.

29
Kevin

Le comptage de base est effectué comme indiqué dans d'autres réponses et dans la documentation relative au porc:

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

Vous avez raison de dire que le comptage est inefficace, même lorsque vous utilisez COUNT, qui est intégré à pig, car il utilise un seul réducteur. Cependant, j’ai appris aujourd’hui que l’un des moyens de l’accélérer serait de réduire l’utilisation RAM de la relation que nous comptons.

En d'autres termes, lorsque nous comptons une relation, nous ne nous soucions pas des données elles-mêmes, alors utilisons aussi peu que possible RAM. Vous étiez sur la bonne voie avec votre première itération du script count.

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

Cela fonctionnera sur des relations beaucoup plus grandes que le script précédent et devrait être beaucoup plus rapide. La principale différence entre ceci et votre script original est que nous n'avons pas besoin de résumer quoi que ce soit.

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

Ce que vous voulez, c'est compter toutes les lignes d'une relation (jeu de données en latin latin)

C'est très facile en suivant les étapes suivantes:

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

Je dois dire que le point important de Kevin étant que, si vous utilisez COUNT au lieu de COUNT_STAR, nous n'aurions que le nombre de lignes pour lesquelles le premier champ n'est pas nul.

De plus, j'aime bien la syntaxe à une ligne de Jérôme, elle est plus concise, mais pour être didactique, je préfère la diviser en deux et ajouter quelques commentaires.

En général je préfère:

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

plus de

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

Voici une version avec optimisation. Toutes les solutions ci-dessus nécessiteraient que porc lise et écrit Tuple complet lors du décompte, ce script ci-dessous écrit simplement '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);
};

L'utiliser comme

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