2016-11-03 44 views
6

Mam następujący dataframe data:używać więcej niż jeden collect_list w jednej kwerendzie w Spark SQL

root 
|-- userId: string 
|-- product: string 
|-- rating: double 

oraz następujące zapytanie:

val result = sqlContext.sql("select userId, collect_list(product), collect_list(rating) from data group by userId") 

Moje pytanie jest to, że robi product i rating w zagregowane tablice pasują do siebie? To znaczy, czy product i rating z tego samego wiersza mają ten sam indeks w zagregowanych tablicach.

Aktualizacja: Począwszy od Spark 2.0.0, można zrobić collect_list na typie konstrukcji, abyśmy mogli wykonać jedną collect_list na kolumnie złożonej. Ale dla wersji pre 2.0.0 można używać tylko wersji collect_list na typie pierwotnym.

Odpowiedz

6

Uważam, że nie ma wyraźnej gwarancji, że wszystkie tablice będą miały tę samą kolejność. Spark SQL używa wielu optymalizacji, a pod pewnymi warunkami nie ma gwarancji, że wszystkie agregacje są zaplanowane w tym samym czasie (jednym z przykładów jest agregacja z DISTINCT). Ponieważ wymiana (przetasowanie) skutkuje niedeterministycznym porządkiem, teoretycznie możliwe jest, że kolejność będzie się różnić.

Tak więc, chociaż powinno działać w praktyce, może to być ryzykowne i wprowadzić kilka trudnych do wykrycia błędów.

Jeśli Spark 2.0.0 lub nowszej można agregować kolumny non-atomowe z collect_list:

SELECT userId, collect_list(struct(product, rating)) FROM data GROUP BY userId 

Jeśli używasz starszej wersji można spróbować użyć wyraźne partycje i porządek:

WITH tmp AS (
    SELECT * FROM data DISTRIBUTE BY userId SORT BY userId, product, rating 
) 
SELECT userId, collect_list(product), collect_list(rating) 
FROM tmp 
GROUP BY userId 
+0

Jak używać 'cogroup' dla dużych zbiorów danych, np. Gdy używam' collect() ', to wyrzuca z pamięci wyjątek' rdd1 = rdd2.cogroup (rdd3) .collect'. Czy możesz pomóc w tej sprawie [https://stackoverflow.com/questions/47180307/how-to-use-cogroup-for-large-datasets]. mogę partycjonować pomoc Jestem nowy, aby zainicjować jakąkolwiek pomoc, aby rozwiązać ten problem. – Vignesh