2016-08-25 5 views
0

私はApacheの新機能phoenix.weはphoenix udfsを書く必要があります。しかし、私はそれについて非常に限られたドキュメントを見つけました:ブログ: http://phoenix-hbase.blogspot.in/2013/04/how-to-add-your-own-built-in-function.html 上記のリンクは単なるi/pとo/pタイプの非常に単純な機能を提供します。 私は1週間以来検索していますが、複数のパラメータを取り、入力に基づいて異なるデータ型を返す評価関数を書く方法を説明するドキュメントは見つかりませんでした。私は現在、組み込み関数のphoenixソースコードを理解しています。これは面倒です。Phoenix UDFの包括的なドキュメントがあります。Apacheが必要ですPhoenix UDFガイド

+0

私は.sqllineコマンドからオーバーロードされたUDFを登録することができますどのように迅速 – Manju

+0

を提案してください、あなたはhttp://phoenix.apache.org/udf.htmlことをしようとしたのですか? – Normal

答えて

2

私もPhoenixを試していて、UDFを書く必要があります。これまでに私が学んだことがいくつかあります。

次の方法で複数の入力を取るUDFを作成することができますので、
@FunctionParseNode.BuiltInFunction( name = BitmapUnionUDF.NAME, args = { @FunctionParseNode.Argument(allowedTypes = {PBinary.class}), @FunctionParseNode.Argument(allowedTypes = {PBinary.class}) } ) public class BitmapIntersectionLengthUDF extends ScalarFunction {

2)評価関数の内部パラメータにアクセスするようにクラスの

1)の定義二つの引数を
Expression arg1 = getChildren().get(0); Expression arg2 = getChildren().get(1);

3)各パラメータの式から実際にバイト値を取得するには

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

- これは、あなたが変換することができますバイト配列を返します - これは、arg1に
ptr.copyBytes()

の値のバイトを取得)arg1に
4の値を指すようにPTRを設定適切なタイプに変換します。

5)jarファイルを登録し、 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は何のconfigs jarファイルとは、設定方法/どこに配置するかのヒントを持っている機能。また

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

udfを正常にデプロイして使用しました。以下のリンクをクリックして、手順に従ってください:https://phoenix-hbase.blogspot.in/2013/04/how-to-add-your-own-built-in-function.html?showComment=1486986513816 –

+1

回答の詳細を回答に含めてください。私たちはユーザーが外部サイトへのリンクをたどって答えを見つけることを期待していません。 – ChrisF

+0

@MohitGarg私はあなたの指示に従い、ここにこだわっています:http://stackoverflow.com/questions/42825482/phoenix-udf-not-working 私を助けることができますか? –

関連する問題