2016-08-25 4 views
0

Ich bin neu in Apache Phoenix.Wir müssen Phoenix UDFs schreiben. Aber ich habe sehr begrenzte Dokumentation darüber gefunden: auf dem Blog: http://phoenix-hbase.blogspot.in/2013/04/how-to-add-your-own-built-in-function.html Über den Link gibt nur sehr einfache Funktion, die nur einzelne i/p und o/p-Typ hat. Ich suche seit einer Woche, konnte aber kein Dokument finden, das erklärt, wie man eine Auswertungsfunktion schreibt, die mehrere Parameter annimmt und verschiedene Datentypen basierend auf Eingaben zurückgeben kann. Alles, was ich derzeit habe, ist das Verständnis von Phoenix-Quellcode von eingebauten Funktionen. Das ist umständlich. Gibt es eine umfassende Dokumentation von Phoenix UDFs.Benötigen Sie Apache Phoenix UDFs Anleitung

+0

Zusätzlich bitte vorschlagen, wie kann ich überladene UDF erst registrieren .sqlline Prompt Befehl – Manju

+0

Sie, dass http://phoenix.apache.org/udf.html versucht haben? – Normal

Antwort

2

Ich probiere auch Phoenix und muss UDFs schreiben. Hier sind ein paar Dinge, die ich bisher gelernt habe.

Sie können eine UDF erstellen, die durch mehrere Eingänge nimmt:

1) zwei Argumente für die Klasse wie so
@FunctionParseNode.BuiltInFunction( name = BitmapUnionUDF.NAME, args = { @FunctionParseNode.Argument(allowedTypes = {PBinary.class}), @FunctionParseNode.Argument(allowedTypes = {PBinary.class}) } ) public class BitmapIntersectionLengthUDF extends ScalarFunction {

2) Zugriff auf die Parameter innerhalb der Funktion auszuwerten
Expression arg1 = getChildren().get(0); Expression arg2 = getChildren().get(1);

3) Um die Byte-Werte aus den Ausdrücken für jeden der Parameter zu erhalten:

if (!arg1.evaluate(tuple, ptr)) { return false; }

- Damit war der ptr auf den Wert von arg1 Punkt
4) Rufen Sie die Bytes des Wertes für arg1
ptr.copyBytes()

- Das wird ein Byte-Array zurück, die Sie konvertieren in den passenden Typ.

5) Registrieren Sie das Glas und Funktion CREATE FUNCTION BITMAP_INTERSECTION_LENGTH(varbinary,varbinary) returns integer as 'com.xxx.yyyy.zzz.BitmapIntersectionLengthUDF' using jar '/path/to/jar';

6) phoenix.apache.org/udf.html mehr Tipps hat wie/wo das Glas zu platzieren und configs, was zu setzen.

0
package com.mohitgarg.hadoop.phoenixudf; 

import java.math.BigDecimal; 
import java.sql.SQLException; 
import java.util.List; 

import org.apache.hadoop.hbase.io.ImmutableBytesWritable; 
import org.apache.phoenix.compile.KeyPart; 
import org.apache.phoenix.expression.Expression; 
import org.apache.phoenix.expression.function.ScalarFunction; 
import org.apache.phoenix.parse.FunctionParseNode.Argument; 
import org.apache.phoenix.parse.FunctionParseNode.BuiltInFunction; 
import org.apache.phoenix.schema.tuple.Tuple; 
import org.apache.phoenix.schema.types.PDataType; 
import org.apache.phoenix.schema.types.PDecimal; 
import org.apache.phoenix.schema.types.PInteger; 
import org.apache.phoenix.schema.types.PVarchar; 

/** 
* 
* @author mohit.garg 
* 
*/ 
@BuiltInFunction(name = PaymentAmountUDF.FUNC_NAME, args = { @Argument(allowedTypes = {PVarchar.class}), 
     @Argument(allowedTypes = {PInteger.class}), 
     @Argument(allowedTypes = {PDecimal.class}), 
     @Argument(allowedTypes = {PDecimal.class}), 
     @Argument(allowedTypes = {PDecimal.class}) 
}) 
public class PaymentAmountUDF extends ScalarFunction { 

    public static final String FUNC_NAME = "PaymentAmount"; 

    public PaymentAmountUDF() { 
    } 

    public PaymentAmountUDF(List<Expression> children) throws SQLException { 
     super(children); 
    } 

    @Override 
    public String getName() { 
     return FUNC_NAME; 
    } 

    /** 
    * Determines whether or not a function may be used to form the start/stop 
    * key of a scan 
    * 
    * @return the zero-based position of the argument to traverse into to look 
    *   for a primary key column reference, or {@value #NO_TRAVERSAL} if 
    *   the function cannot be used to form the scan key. 
    */ 
    public int getKeyFormationTraversalIndex() { 
     return NO_TRAVERSAL; 
    } 

    /** 
    * Manufactures a KeyPart used to construct the KeyRange given a constant 
    * and a comparison operator. 
    * 
    * @param childPart 
    *   the KeyPart formulated for the child expression at the 
    *   {@link #getKeyFormationTraversalIndex()} position. 
    * @return the KeyPart for constructing the KeyRange for this function. 
    */ 
    public KeyPart newKeyPart(KeyPart childPart) { 
     return null; 
    } 

    /** 
    * Determines whether or not the result of the function invocation will be 
    * ordered in the same way as the input to the function. Returning YES 
    * enables an optimization to occur when a GROUP BY contains function 
    * invocations using the leading PK column(s). 
    * 
    * @return YES if the function invocation will always preserve order for the 
    *   inputs versus the outputs and false otherwise, YES_IF_LAST if the 
    *   function preserves order, but any further column reference would 
    *   not continue to preserve order, and NO if the function does not 
    *   preserve order. 
    */ 
    public OrderPreserving preservesOrder() { 
     return OrderPreserving.NO; 
    } 

    /** 
    * is the method to be implemented which provides access to the Tuple 
    * 
    * @param tuple 
    *   Single row result during scan iteration 
    * @param ptr 
    *   Pointer to byte value being accessed 
    * @return 
    */ 
    public boolean evaluate(Tuple tuple, ImmutableBytesWritable ptr) { 

     String frequency = null; 
     Integer term = null; 
     BigDecimal interestRate = null; 
     BigDecimal loanAmount = null; 
     BigDecimal fee = null; 

     for (int i = 0; i <= 4; i++) { 

      Expression arg = getChildren().get(i); 
      if (!arg.evaluate(tuple, ptr)) { 
       return false; 
      } 
      switch (i) { 
      case 0: 
       frequency = new String(ptr.copyBytes()); 
       break; 
      case 1: 
       term = (Integer) PInteger.INSTANCE.toObject(ptr); 
       break; 
      case 2: 
       interestRate = (BigDecimal)PDecimal.INSTANCE.toObject(ptr, PDecimal.INSTANCE); 
       break; 
      case 3:   
       loanAmount = (BigDecimal)PDecimal.INSTANCE.toObject(ptr, PDecimal.INSTANCE); 
       break; 
      case 4:   
       fee = (BigDecimal)PDecimal.INSTANCE.toObject(ptr, PDecimal.INSTANCE);  
       break; 
      default: 
       return true; 
      } 
     } 

     int tp = 0; 
     String upcaseFrequency = frequency.toUpperCase(); 
     if(upcaseFrequency.equals("M")) { 
      tp = 12; 
     } else if(upcaseFrequency.equals("T")) { 
      tp = 13; 
     } else if(upcaseFrequency.equals("B")) { 
      tp = 26; 
     } else if(upcaseFrequency.equals("S")) { 
      tp = 24; 
     } else if(upcaseFrequency.equals("W")) { 
      tp = 52; 
     } 

     int inst = (int) (Math.ceil((term/12) * tp)); 
     double r = interestRate.doubleValue()/tp; 
     double po = 1 - Math.pow(r + 1, -1 * inst); 
     double por = r/po; 
     double paymentAmount = ((por) * (loanAmount.doubleValue() + fee.doubleValue())); 
     BigDecimal decimalPaymentAmount = BigDecimal.valueOf(paymentAmount).setScale(2, BigDecimal.ROUND_HALF_UP); 
     ptr.set(PDecimal.INSTANCE.toBytes(decimalPaymentAmount)); 

     return true; 
    } 

    public PDataType getDataType() { 
     return PDecimal.INSTANCE; 
    } 

} 
+0

Ich habe ein UDF erfolgreich eingesetzt und benutzt. Bitte folgen Sie meinem Kommentar im folgenden Link, um die Schritte zu folgen .: https://phoenix-hbase.blogspot.in/2013/04/how-to-add-your-own-built-in-function.html?showComment=1486986513816 –

+1

Bitte fügen Sie die Details der Antwort hier in der Antwort ein. Wir erwarten nicht, dass Benutzer Links zu externen Websites folgen, um die Antwort zu finden. – ChrisF

+0

@MohitGarg Ich folgte Ihrer Anweisung und stecke hier fest: http://StackOverflow.com/Questions/42825482/Phoenix-UDF-not-working können Sie mir helfen? –

Verwandte Themen