Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
需要ApachePhoenix UDFs指南吗_Apache_Phoenix - Fatal编程技术网

需要ApachePhoenix UDFs指南吗

需要ApachePhoenix UDFs指南吗,apache,phoenix,Apache,Phoenix,我是apache phoenix的新手。我们需要编写phoenix UDF。但我在博客上找到的文档非常有限: 上面的链接只提供了非常简单的函数,它只有单一的i/p和o/p类型。 我从一个星期开始搜索,但找不到任何文档解释如何编写包含多个参数的求值函数,该函数可以根据输入返回不同的数据类型。目前我只了解phoenix内置函数的源代码。这很麻烦。是否有关于phoenix UDF的全面文档。我也在试用phoenix,需要编写UDF。到目前为止,我学到了一些东西 您可以通过以下方式创建接受多个输入的自定

我是apache phoenix的新手。我们需要编写phoenix UDF。但我在博客上找到的文档非常有限: 上面的链接只提供了非常简单的函数,它只有单一的i/p和o/p类型。
我从一个星期开始搜索,但找不到任何文档解释如何编写包含多个参数的求值函数,该函数可以根据输入返回不同的数据类型。目前我只了解phoenix内置函数的源代码。这很麻烦。是否有关于phoenix UDF的全面文档。

我也在试用phoenix,需要编写UDF。到目前为止,我学到了一些东西

您可以通过以下方式创建接受多个输入的自定义项:

1) 为类定义两个参数,如so
@FunctionParseNode.BuiltInFunction(
name=BitmapUnionUDF.name,
args={
@FunctionParseNode.Argument(allowedTypes={PBinary.class}),
@FunctionParseNode.Argument(allowedTypes={PBinary.class})
}
)
公共类BitmapIntersectionLengthUDF扩展了ScalarFunction{

2) 访问评估函数中的参数
表达式arg1=getChildren().get(0); 表达式arg2=getChildren().get(1);

3) 要从每个参数的表达式中实际获取字节值,请执行以下操作:

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

--这将ptr设置为指向arg1的值
4) 检索arg1值的字节
ptr.copyBytes()

--这将返回一个字节数组,您可以将其转换为适当的类型

5) 注册jar和函数
CREATE FUNCTION BITMAP\u INTERSECTION\u LENGTH(varbinary,varbinary)使用jar'/path/to/jar'将整数返回为'com.xxx.yyyy.zzz.BitmapIntersectionLengthUDF';


6) 有更多关于如何/在何处放置jar以及如何设置配置的提示。

我也在尝试Phoenix,需要编写UDF。以下是我到目前为止学到的一些东西

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;
    }

}
您可以通过以下方式创建接受多个输入的自定义项:

1) 为类定义两个参数,如so
@FunctionParseNode.BuiltInFunction(
name=BitmapUnionUDF.name,
args={
@FunctionParseNode.Argument(allowedTypes={PBinary.class}),
@FunctionParseNode.Argument(allowedTypes={PBinary.class})
}
)
公共类BitmapIntersectionLengthUDF扩展了ScalarFunction{

2) 访问评估函数中的参数
表达式arg1=getChildren().get(0); 表达式arg2=getChildren().get(1);

3) 要从每个参数的表达式中实际获取字节值,请执行以下操作:

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

--这将ptr设置为指向arg1的值
4) 检索arg1值的字节
ptr.copyBytes()

--这将返回一个字节数组,您可以将其转换为适当的类型

5) 注册jar和函数
CREATE FUNCTION BITMAP\u INTERSECTION\u LENGTH(varbinary,varbinary)使用jar'/path/to/jar'将整数返回为'com.xxx.yyyy.zzz.BitmapIntersectionLengthUDF';

6) 有更多关于如何/在何处放置jar以及设置配置的提示。

package com.mohitgarg.hadoop.phoenixudf;
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;
    }

}
导入java.math.BigDecimal; 导入java.sql.SQLException; 导入java.util.List; 导入org.apache.hadoop.hbase.io.ImmutableBytesWritable; 导入org.apache.phoenix.compile.KeyPart; 导入org.apache.phoenix.expression.expression; 导入org.apache.phoenix.expression.function.ScalarFunction; 导入org.apache.phoenix.parse.FunctionParseNode.Argument; 导入org.apache.phoenix.parse.FunctionParseNode.BuiltInFunction; 导入org.apache.phoenix.schema.tuple.tuple; 导入org.apache.phoenix.schema.types.PDataType; 导入org.apache.phoenix.schema.types.PDecimal; 导入org.apache.phoenix.schema.types.PInteger; 导入org.apache.phoenix.schema.types.PVarchar; /** * *@author mohit.garg * */ @内置函数(name=PaymentAmountUDF.FUNC_name,args={@Argument(allowedTypes={PVarchar.class}), @参数(allowedTypes={PInteger.class}), @参数(allowedTypes={PDecimal.class}), @参数(allowedTypes={PDecimal.class}), @参数(allowedTypes={PDecimal.class}) }) 公共类PaymentAmountUDF扩展了ScalarFunction{ 公共静态最终字符串FUNC_NAME=“PaymentAmount”; 公共支付金额UDF(){ } public PaymentAmountUDF(列出子项)引发SQLException{ 超级(儿童); } @凌驾 公共字符串getName(){ 返回函数名; } /** *确定是否可以使用函数来形成启动/停止 *扫描键 * *@返回要遍历以查看的参数的从零开始的位置 *对于主键列引用,或{@value#NO_TRAVERSAL}如果 *该功能不能用于形成扫描键。 */ public int getKeyFormationTraversalIndex(){ 返回NO_遍历; } /** *制造用于构造给定常数的KeyRange的KeyPart *和一个比较运算符。 * *@param childPart *关键部分是为儿童表达在 *{@link#getKeyFormationTraversalIndex()}位置。 *@返回用于构造此函数的KeyRange的KeyPart。 */ 公钥部分newKeyPart(KeyPart-childPart){ 返回null; } /** *确定函数调用的结果是否为 *按与函数输入相同的方式排序。返回“是” *允许在GROUP BY包含函数时进行优化 *使用前导PK列的调用。