Ich habe folgende Tabelle in Hive
benutzer-ID, Benutzername, Benutzeradresse, Klicks, Impressionen, Seiten-ID, Seitenname
Ich muss die Top-5-Benutzer (Benutzer-ID, Benutzername, Benutzeradresse) durch Klicks für jede Seite herausfinden [Seiten-ID, Seitenname].
Ich verstehe, dass wir zuerst nach [Seiten-ID, Seitenname] gruppieren müssen, und innerhalb jeder Gruppe, die ich bestellen möchte, [Klicks, Impressionen]. Adresse] für jede Seite, aber ich finde es schwierig, die Abfrage zu erstellen.
Wie können wir das mit Hive UDF tun?
Sie können dies mit einer hier beschriebenen Rang () - UDF tun: http://ragrawal.wordpress.com/2011/11/18/extract-top-n-records-in-each-group-in-hadoophive/
SELECT page-id, user-id, clicks
FROM (
SELECT page-id, user-id, rank(user-id) as rank, clicks
FROM mytable
DISTRIBUTE BY page-id, user-id
SORT BY page-id, user-id, clicks desc
) a
WHERE rank < 5
ORDER BY page-id, rank
Überarbeitete Antwort, behebt den Fehler, wie von @Himanshu Gahlot erwähnt
SELECT page-id, user-id, clicks
FROM (
SELECT page-id, user-id, rank(page-id) as rank, clicks FROM (
SELECT page-id, user-id, clicks FROM mytable
DISTRIBUTE BY page-id
SORT BY page-id, clicks desc
) a ) b
WHERE rank < 5
ORDER BY page-id, rank
Beachten Sie, dass UDAF rank () auf die Page-ID-Spalte angewendet wird, deren neuer Wert zum Zurücksetzen oder Erhöhen des Rank-Zählers verwendet wird (z. B. Reset-Zähler für jede Seiten-ID-Partition).
Ab Hive 0.11 können Sie dies mit der integrierten rank () - Funktion von Hive und der einfacheren Semantik mit den integrierten Analytics- und Windowing-Funktionen von Hive durchführen. Leider konnte ich nicht so viele Beispiele finden, wie ich mir gewünscht hätte, aber sie sind wirklich sehr nützlich. Wenn Sie diese verwenden, sind sowohl rank () als auch WhereWithRankCond integriert. Sie können also Folgendes tun:
SELECT page-id, user-id, clicks
FROM (
SELECT page-id, user-id, rank()
over (PARTITION BY page-id ORDER BY clicks DESC) as rank, clicks
FROM my table
) ranked_mytable
WHERE ranked_mytable.rank < 5
ORDER BY page-id, rank
Keine UDF erforderlich und nur eine Unterabfrage! Außerdem ist die gesamte Ranglogik lokalisiert.
Einige weitere (aber nicht genug für meinen Geschmack) Beispiele dieser Funktionen finden Sie in diesem Jira und auf diesem Blog dieses Kerls .
Sie können each_top_k
function of hivemall
für eine effiziente Top-k-Berechnung in Apache Hive verwenden.
wählen Seiten-ID, Benutzeridentifikation, Klicks von ( Auswahl each_top_k (5, Seiten-ID, Klicks, Seiten-ID, Benutzer-ID) as (Rang, Klicks, Seiten-ID, Benutzer-ID) from ( select page-id, benutzer-id, klickt aus mytable DISTRIBUTE BY page-id SORT BY page-id ) t1 ) t2 Reihenfolge nach Seiten-ID ASC, klickt auf DESC
Die each_top_k
-UDTF ist im Vergleich zu anderen Methoden, die top-k-Abfragen (z. B. distributed by/rank
) in Hive ausführen, sehr schnell, da sie nicht die gesamte Rangfolge für das Zwischenergebnis enthält.
Nehmen wir an, Ihre Daten sehen folgendermaßen aus:
page-id user-id clicks
page1 user1 10
page1 user2 10
page1 user3 9
page1 user4 8
page1 user5 7
page1 user6 7
page1 user7 6
page1 user8 5
page2 user1 20
page2 user2 19
page2 user3 18
Unter Query erhalten Sie:
SELECT page-id, user-id, clicks, rank
FROM (
SELECT page-id, user-id, rank()
over (PARTITION BY page-id ORDER BY clicks DESC) as rank, clicks
FROM your_table
) ranked_table
WHERE ranked_table.rank <= 5
Ergebnis:
page-id user-id clicks rank
page1 user1 10 1
page1 user2 10 1
page1 user3 9 3
page1 user4 8 4
page1 user5 7 5
page1 user6 7 5
page2 user1 20 1
page2 user2 19 2
page2 user3 18 3
Für page1 erhalten Sie also 6 Nutzer, da Nutzer mit der gleichen Anzahl von Klicks gleich bewertet werden.
Wenn Sie jedoch nach genau 5 Benutzern suchen, wählen Sie nach dem Zufallsprinzip aus, falls mehrere Benutzer in denselben Rang fallen. Sie können die folgende Abfrage verwenden
SELECT page-id, user-id, clicks, rank
FROM (
SELECT page-id, user-id, row_number()
over (PARTITION BY page-id ORDER BY clicks DESC) as rank, clicks
FROM your_table
) ranked_table
WHERE ranked_table.rank <= 5
Ergebnis:
page-id user-id clicks rank
page1 user1 10 1
page1 user2 10 2
page1 user3 9 3
page1 user4 8 4
page1 user5 7 5
page2 user1 20 1
page2 user2 19 2
page2 user3 18 3