Apache Pig UDF: ตอนที่ 1 - ฟังก์ชั่น Eval, Aggregate & Filter



โพสต์นี้อธิบายเกี่ยวกับ Apache Pig UDF - Eval, Aggregate & Filter Functions ดูที่ Eval, Aggregate & Filter Functions

Apache Pig ให้การสนับสนุนอย่างกว้างขวางสำหรับฟังก์ชันที่ผู้ใช้กำหนดเอง (UDF) เพื่อระบุการประมวลผลแบบกำหนดเอง ปัจจุบัน Pig UDF สามารถทำงานได้สามภาษา: Java, Python, JavaScript และ Ruby การสนับสนุนที่กว้างขวางที่สุดมีให้สำหรับฟังก์ชัน Java





Java UDF สามารถเรียกใช้ได้หลายวิธี UDF ที่ง่ายที่สุดสามารถขยาย EvalFunc ได้ซึ่งต้องใช้ฟังก์ชัน exec เท่านั้น Eval UDF ทุกคนต้องใช้สิ่งนี้ นอกจากนี้หากฟังก์ชันเป็นพีชคณิตก็สามารถใช้อินเทอร์เฟซพีชคณิตเพื่อปรับปรุงประสิทธิภาพการสืบค้นได้อย่างมาก

ความสำคัญของ UDF ในสุกร:

Pig อนุญาตให้ผู้ใช้รวมตัวดำเนินการที่มีอยู่กับรหัสของตนเองหรือของผู้อื่นผ่าน UDF ข้อดีของ Pig คือความสามารถในการให้ผู้ใช้รวมตัวดำเนินการกับรหัสของตนเองหรือของผู้อื่นผ่าน UDF จนถึงเวอร์ชัน 0.7 UDF ทั้งหมดต้องเขียนด้วย Java และใช้งานเป็นคลาส Java วิธีนี้ช่วยให้เพิ่ม UDF ใหม่ให้กับ Pig ได้ง่ายขึ้นโดยการเขียนคลาส Java และแจ้ง Pig เกี่ยวกับไฟล์ JAR



หมูเองก็มาพร้อมกับ UDF บางตัว ก่อนหน้าเวอร์ชัน 0.8 เป็นชุดที่ จำกัด มากโดยมีเพียงฟังก์ชันการรวม SQL มาตรฐานและอื่น ๆ อีกเล็กน้อย ใน 0.8 มีการเพิ่มการประมวลผลสตริงมาตรฐานคณิตศาสตร์และ UDF ประเภทซับซ้อนจำนวนมาก

Piggybank คืออะไร?

Piggybank คือชุดของ UDF ที่ผู้ใช้สนับสนุนซึ่งเปิดตัวพร้อมกับ Pig Piggybank UDF ไม่รวมอยู่ใน Pig JAR ดังนั้นคุณต้องลงทะเบียนด้วยตนเองในสคริปต์ของคุณ คุณยังสามารถเขียน UDF ของคุณเองหรือใช้สิ่งที่เขียนโดยผู้ใช้อื่น

ฟังก์ชั่นการประเมิน

คลาส UDF ขยายคลาส EvalFunc ซึ่งเป็นฐานสำหรับฟังก์ชัน Eval ทั้งหมด ฟังก์ชัน Evaluation ทั้งหมดขยายคลาส Java 'org.apache.pig.EvalFunc 'มันถูกกำหนดพารามิเตอร์ด้วยชนิดผลตอบแทนของ UDF ซึ่งเป็น Java String ในกรณีนี้ เมธอดหลักในคลาสนี้คือ 'exec' บรรทัดที่ 1 ของโค้ดระบุว่าฟังก์ชันเป็นส่วนหนึ่งของแพ็กเกจ myudfs



ใช้เวลาหนึ่งระเบียนและส่งกลับผลลัพธ์หนึ่งรายการซึ่งจะถูกเรียกใช้สำหรับทุกระเบียนที่ผ่านไปป์ไลน์การดำเนินการ ใช้ทูเพิลซึ่งมีฟิลด์ทั้งหมดที่สคริปต์ส่งผ่านไปยัง UDF ของคุณเป็นอินพุต จากนั้นจะส่งคืนประเภทที่คุณกำหนดพารามิเตอร์ EvalFunc

ฟังก์ชันนี้ถูกเรียกใช้ในทุกอินพุตทูเปิล อินพุตในฟังก์ชันคือทูเพิลที่มีพารามิเตอร์อินพุตตามลำดับที่ส่งผ่านไปยังฟังก์ชันในสคริปต์ Pig ในตัวอย่างที่แสดงด้านล่างฟังก์ชันรับสตริงเป็นอินพุต ฟังก์ชันต่อไปนี้จะแปลงสตริงจากตัวพิมพ์เล็กเป็นตัวพิมพ์ใหญ่ เมื่อใช้ฟังก์ชันแล้วจำเป็นต้องรวบรวมและรวมไว้ใน JAR

อะไรคือความแตกต่างระหว่าง javascript และ jquery
แพ็กเกจ myudfs import java.io.IOException import org.apache.pig.EvalFunc import org.apache.pig.data คลาสพับลิก UPPER ขยาย EvalFunc {public String exec (Tuple input) พ่น IOException {if (input == null || input.size () == 0) return null ลอง {String str = (String) input.get (0) return str.toUpperCase ()} catch (Exception e) {throw new IOException ('Caught exception processing input row', จ)}}}

ฟังก์ชันรวม:

ฟังก์ชันรวมเป็นฟังก์ชัน Eval อีกประเภทหนึ่ง โดยปกติฟังก์ชันรวมจะใช้กับข้อมูลที่จัดกลุ่ม ฟังก์ชัน Aggregate รับกระเป๋าและส่งคืนค่าสเกลาร์ คุณลักษณะที่น่าสนใจและมีคุณค่าของฟังก์ชัน Aggregate จำนวนมากคือสามารถคำนวณได้ทีละน้อยในลักษณะกระจาย ใน Hadoop world นั่นหมายความว่าการคำนวณบางส่วนสามารถทำได้โดย Map และ Combiner และผลลัพธ์สุดท้ายสามารถคำนวณได้โดย Reducer

เป็นสิ่งสำคัญมากที่จะต้องตรวจสอบให้แน่ใจว่าฟังก์ชัน Aggregate ที่เป็นพีชคณิตถูกนำไปใช้เช่นนี้ ตัวอย่างประเภทนี้ ได้แก่ COUNT, MIN, MAX และ AVERAGE ในตัว

นับ เป็นตัวอย่างของฟังก์ชันพีชคณิตที่เราสามารถนับจำนวนองค์ประกอบในเซตย่อยของข้อมูลจากนั้นจึงรวมจำนวนเพื่อสร้างผลลัพธ์สุดท้าย มาดูการใช้งานฟังก์ชัน COUNT:

คลาสสาธารณะ COUNT ขยาย EvalFunc ใช้พีชคณิต {public Long exec (Tuple input) พ่น IOException {return count (input)} public String getInitial () {return Initial.class.getName ()} public String getIntermed () {return Intermed.class. getName ()} สตริงสาธารณะ getFinal () {return Final.class.getName ()} คลาสสาธารณะแบบคงที่ Initial ขยาย EvalFunc {public Tuple exec (Tuple input) พ่น IOException {return TupleFactory.getInstance (). newTuple (count (input)) }} คลาสสาธารณะแบบคงที่ Intermed ขยาย EvalFunc {public Tuple exec (Tuple input) พ่น IOException {return TupleFactory.getInstance (). newTuple (sum (input))}} static public class Final ขยาย EvalFunc {public Tuple exec (Tuple input) พ่น IOException {return sum (input)}} static protected Long count (Tuple input) พ่น ExecException {Object values ​​= input.get (0) if (values ​​instanceof DataBag) return ((DataBag) values) .size () else if (values อินสแตนซ์ของแผนที่) ส่งคืนค่า Long (((แผนที่)) .size ())} แบบคงที่ป้องกันผลรวมยาว (Tuple i nput) พ่น ExecException, NumberFormatException {DataBag values ​​= (DataBag) input.get (0) long sum = 0 สำหรับ (Iterator (Tuple) it = values.iterator () it.hasNext ()) {Tuple t = it.next ( ) sum + = (Long) t.get (0)} return sum}}

COUNT ใช้อินเทอร์เฟซพีชคณิตซึ่งมีลักษณะดังนี้:

อินเทอร์เฟซสาธารณะพีชคณิต {public String getInitial () public String getIntermed () public String getFinal ()}

เพื่อให้ฟังก์ชันเป็นพีชคณิตจำเป็นต้องใช้อินเทอร์เฟซพีชคณิตที่ประกอบด้วยคำจำกัดความของคลาสสามคลาสที่ได้มาจาก EvalFunc สัญญาคือการทำงานของคลาสเริ่มต้นจะถูกเรียกครั้งเดียวและส่งต่อไปยังทูเพิลอินพุตดั้งเดิม ผลลัพธ์คือทูเพิลที่มีผลลัพธ์บางส่วน ฟังก์ชัน exec ของคลาส Intermed สามารถเรียกได้ว่าเป็นศูนย์หรือมากกว่าและใช้เวลาเป็นอินพุตทูเพิลที่มีผลลัพธ์บางส่วนที่สร้างโดยคลาสเริ่มต้นหรือโดยการเรียกใช้คลาส Intermed ก่อนหน้าและสร้างทูเพิลที่มีผลลัพธ์บางส่วนอื่น สุดท้ายฟังก์ชัน exec ของคลาสสุดท้ายจะถูกเรียกและให้ผลลัพธ์สุดท้ายเป็นประเภทสเกลาร์

ฟังก์ชั่นตัวกรอง:

ฟังก์ชันตัวกรองคือฟังก์ชัน Eval ที่ส่งคืนค่าบูลีน สามารถใช้ได้ทุกที่ที่นิพจน์บูลีนเหมาะสมรวมถึงตัวดำเนินการ FILTER หรือนิพจน์ Bincond Apache Pig ไม่รองรับ Boolean โดยสิ้นเชิงดังนั้นฟังก์ชัน Filter จึงไม่สามารถปรากฏในคำสั่งเช่น ‘Foreach’ ซึ่งผลลัพธ์จะถูกส่งออกไปยังตัวดำเนินการอื่น อย่างไรก็ตามสามารถใช้ฟังก์ชันตัวกรองในคำสั่งตัวกรอง

ตัวอย่างด้านล่างใช้ฟังก์ชัน IsEmpty:

import java.io.IOException import java.util.Map import org.apache.pig.FilterFunc import org.apache.pig.PigException import org.apache.pig.backend.executionengine.ExecException import org.apache.pig.data.DataBag import org.apache.pig.data.Tuple import org.apache.pig.data.DataType / ** * กำหนดว่ากระเป๋าหรือแผนที่ว่างเปล่า * / public class IsEmpty ขยาย FilterFunc {@Override public Boolean exec (Tuple input) พ่น IOException {try {Object values ​​= input.get (0) if (values ​​instanceof DataBag) return ((DataBag) values) .size () == 0 else if (values ​​instanceof Map) return ((Map) values) .size () == 0 else {int errCode = 2102 String msg = 'Can not test a' + DataType.findTypeName (values) + 'for Emptiness' โยน ExecException ใหม่ (msg, errCode, PigException.BUG)}} catch (ExecException ee) {throw ee}}}