الوظائف العددية المعرفة من قبل المستخدم - Scala
تحتوي هذه المقالة على أمثلة على دالة Scala المعرفة من قبل المستخدم (UDF). وهو يوضح كيفية تسجيل UDFs، وكيفية استدعاء UDFs، والمحاذير المتعلقة بترتيب تقييم التعبيرات الفرعية في Spark SQL. راجع الدوال العددية الخارجية المعرفة من قبل المستخدم (UDFs) لمزيد من التفاصيل.
ملاحظة
يتطلب Scala UDFs على موارد الحوسبة الممكنة لكتالوج Unity مع وضع الوصول المشترك Databricks Runtime 14.2 وما فوق.
val squared = (s: Long) => {
s * s
}
spark.udf.register("square", squared)
spark.range(1, 20).createOrReplaceTempView("test")
%sql select id, square(id) as id_squared from test
import org.apache.spark.sql.functions.{col, udf}
val squared = udf((s: Long) => s * s)
display(spark.range(1, 20).select(squared(col("id")) as "id_squared"))
لا يضمن Spark SQL (بما في ذلك SQL وDataFrame وDataset APIs) ترتيب تقييم التعبيرات الفرعية. على وجه الخصوص، لا يتم بالضرورة تقييم مدخلات عامل التشغيل أو الدالة من اليسار إلى اليمين أو بأي ترتيب ثابت آخر. على سبيل المثال، لا تحتوي التعبيرات والمنطقية AND
OR
على دلالات "دائرة قصيرة" من اليسار إلى اليمين.
لذلك، من الخطر الاعتماد على الآثار الجانبية أو ترتيب تقييم التعبيرات المنطقية، وترتيب WHERE
العبارات و HAVING
، حيث يمكن إعادة ترتيب هذه التعبيرات والعبارات أثناء تحسين الاستعلام والتخطيط. على وجه التحديد، إذا كان UDF يعتمد على دلالات الدوائر القصيرة في SQL للتحقق من القيم الخالية، فلا يوجد ما يضمن أن التحقق من القيم الخالية سيحدث قبل استدعاء UDF. على سبيل المثال،
spark.udf.register("strlen", (s: String) => s.length)
spark.sql("select s from test1 where s is not null and strlen(s) > 1") // no guarantee
لا تضمن هذه WHERE
العبارة strlen
استدعاء UDF بعد تصفية القيم الخالية.
لإجراء فحص القيم الخالية المناسبة، نوصي بالقيام بأي مما يلي:
- جعل UDF نفسه مدركا للقيم الخالية والقيام بالتحقق من القيم الخالية داخل UDF نفسه
- استخدام
IF
أوCASE WHEN
التعبيرات لإجراء فحص القيم الخالية واستدعاء UDF في فرع شرطي
spark.udf.register("strlen_nullsafe", (s: String) => if (s != null) s.length else -1)
spark.sql("select s from test1 where s is not null and strlen_nullsafe(s) > 1") // ok
spark.sql("select s from test1 where if(s is not null, strlen(s), null) > 1") // ok
ملاحظة
يتم دعم هذه الميزة على المجموعات الممكنة لكتالوج Unity مع وضع الوصول المشترك في Databricks Runtime 15.4 وما فوق.
تسمح لك واجهات برمجة تطبيقات مجموعة البيانات التي تمت كتابتها بتشغيل تحويلات مثل الخريطة والتصفية والتجميعات على مجموعات البيانات الناتجة باستخدام دالة معرفة من قبل المستخدم.
على سبيل المثال، يستخدم map()
تطبيق Scala التالي واجهة برمجة التطبيقات لتعديل رقم في عمود نتيجة إلى سلسلة بادئة.
spark.range(3).map(f => s"row-$f").show()
بينما يستخدم map()
هذا المثال واجهة برمجة التطبيقات، ينطبق هذا أيضا على واجهات برمجة تطبيقات مجموعة البيانات الأخرى، مثل filter()
وmapPartitions()
foreach()
foreachPartition()
reduce()
.flatMap()