做旅游网站选什么空间,ui设计流程培训怎么样,精品网站建设公司,免费网络服务器drill apacheApache Drill允许用户使用ANSI SQL探索任何类型的数据。 这很棒#xff0c;但是Drill的作用远远不止于此#xff0c;它允许您创建自定义函数来扩展查询引擎。 这些自定义函数具有Drill基本操作的所有性能#xff0c;但是允许执行这些性能会使编写这些函数的技巧… drill apache Apache Drill允许用户使用ANSI SQL探索任何类型的数据。 这很棒但是Drill的作用远远不止于此它允许您创建自定义函数来扩展查询引擎。 这些自定义函数具有Drill基本操作的所有性能但是允许执行这些性能会使编写这些函数的技巧比您预期的要复杂。 在本文中我将使用一个非常基本的示例逐步说明如何创建和部署新功能。 请注意您可以在文档中找到许多有关“ 钻取自定义功能”的信息 。 让我们创建一个新函数使您能够屏蔽字符串中的某些字符并使它变得非常简单。 新功能将允许用户从头开始隐藏x个字符然后替换为他们选择的任何字符。 看起来像 MASK( PASSWORD , # , 4 ) ####WORD 您可以在以下Github存储库中找到完整的项目。 如前所述我们可以想象许多高级功能但是我的目标是专注于编写自定义功能的步骤而不是功能的作用。 先决条件 为此您将需要 Java Developer Kit 7或更高版本 Apache Drill 1.1或更高版本 Maven 3.0或更高版本 依存关系 以下Drill依赖项应添加到您的Maven项目中 dependencygroupIdorg.apache.drill.exec/groupIdartifactIddrill-java-exec/artifactIdversion1.1.0/version
/dependency资源 Mask函数是DrillSimpleFunc的实现。 开发人员可以创建两种类型的自定义函数 简单函数这些函数将一行作为输入并产生一个值作为输出 聚合函数接受多行作为输入并产生一个值作为输出 简单功能通常称为UDF代表用户定义的功能。 聚合功能称为UDAF代表用户定义的聚合功能。 在此示例中我们只需要转换每一行上一列的值因此一个简单的函数就足够了。 创建功能 第一步是实现DrillSimpleFunc接口。 package org.apache.drill.contrib.function;import org.apache.drill.exec.expr.DrillSimpleFunc;
import org.apache.drill.exec.expr.annotations.FunctionTemplate;FunctionTemplate(namemask,scope FunctionTemplate.FunctionScope.SIMPLE,nulls FunctionTemplate.NullHandling.NULL_IF_NULL
)
public class SimpleMaskFunc implements DrillSimpleFunc{public void setup() {}public void eval() {}
} 函数的行为由注释驱动第6-10行*函数名称 *函数范围 在我们的例子中为简单*值为NULL时的操作在这种情况下Reverse将仅返回NULL 现在我们需要使用setup()和eval()方法来实现函数的逻辑。 setup是不言自明的在我们这里我们不需要设置任何东西。 eval是该功能的核心。 如您所见此方法没有任何参数并返回void。 那么它是怎样工作的 实际上该函数将动态生成请参阅DrillSimpleFuncHolder 并且输入参数和输出保持器是通过注释的保持器定义的。 让我们来看看这个。 import io.netty.buffer.DrillBuf;
import org.apache.drill.exec.expr.DrillSimpleFunc;
import org.apache.drill.exec.expr.annotations.FunctionTemplate;
import org.apache.drill.exec.expr.annotations.Output;
import org.apache.drill.exec.expr.annotations.Param;
import org.apache.drill.exec.expr.holders.IntHolder;
import org.apache.drill.exec.expr.holders.NullableVarCharHolder;
import org.apache.drill.exec.expr.holders.VarCharHolder;import javax.inject.Inject;FunctionTemplate(name mask,scope FunctionTemplate.FunctionScope.SIMPLE,nulls FunctionTemplate.NullHandling.NULL_IF_NULL
)
public class SimpleMaskFunc implements DrillSimpleFunc {ParamNullableVarCharHolder input;Param(constant true)VarCharHolder mask;Param(constant true)IntHolder toReplace;OutputVarCharHolder out;InjectDrillBuf buffer;public void setup() {}public void eval() {}} 我们需要定义函数的参数。 在这种情况下我们有3个参数每个参数都使用Param批注定义。 此外我们还必须使用Output批注定义返回的值。 我们的mask函数的参数是 可为空的字符串 掩码字符或字符串 从第一个字符开始替换的字符数 该函数返回 一串 对于每个参数您都必须使用一个holder类。 对于String 这由VarCharHolder或NullableVarCharHolder 21、24,30行管理该行提供了一种缓冲区可以有效地管理较大的对象。 由于我们正在处理VarChar您还必须注入另一个缓冲区该缓冲区将用于输出行33-。 请注意Drill实际上并不将Java堆用于查询中正在处理的数据而是将这些数据保留在堆外并为我们管理生命周期而无需使用Java垃圾收集器。 因为我们有了适当的类输入/输出对象所以我们差不多完成了只需要实现eval()方法本身并使用这些对象即可。 public void eval() {// get the value and replace withString maskValue org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.getStringFromVarCharHolder(mask);String stringValue org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(input.start, input.end, input.buffer);int numberOfCharToReplace Math.min(toReplace.value, stringValue.length());// build the mask substringString maskSubString com.google.common.base.Strings.repeat(maskValue, numberOfCharToReplace);String outputValue (new StringBuilder(maskSubString)).append(stringValue.substring(numberOfCharToReplace)).toString();// put the output value in the out bufferout.buffer buffer;out.start 0;out.end outputValue.getBytes().length;buffer.setBytes(0, outputValue.getBytes());
} 代码很简单 获取面具本身-第4行 获取值–第5行 获取要替换的字符数-第7行 生成带有掩码值的新字符串-第10/11行 创建并填充输出缓冲区–第14至17行 但是对于习惯于阅读Java代码的人来说这段代码确实有些奇怪。 之所以会出现这种奇怪现象是因为在查询中执行的最终代码实际上会即时生成。 这使Drill可以利用Java的即时JIT编译器来达到最大速度。 要使此工作有效您必须遵守一些基本规则 不要使用import而是使用完全限定的类名 这是在第10行使用Strings类完成的。 来自Apache Drill中打包的Google Guava API 该ValueHolders类在我们的例子VarCharHolder和IntHolder应该被操纵结构一样所以你必须调用辅助方法例如getStringFromVarCharHolder和toStringFromUTF8 。 调用诸如toString类的toString将导致非常严重的问题。 现在我们准备部署和测试此新功能。 包 再一次由于Drill将生成源代码因此您必须以在classpath中存在该函数的类和源代码的方式准备软件包 。 这不同于通常打包Java代码的方式但是Drill能够进行必要的代码生成是必需的。 Drill使用编译后的代码访问注释并使用源代码进行代码生成。 一种简单的方法是使用maven构建项目尤其是在pom.xml文件中使用如下所示的maven-source-plugin plugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-source-plugin/artifactIdversion2.4/versionexecutionsexecutionidattach-sources/idphasepackage/phasegoalsgoaljar-no-fork/goal/goals/execution/executions
/plugin 现在当您使用mvn package构建时Maven将生成2个jar 带有类和资源的默认jar drill-simple-mask-1.0.jar 第二个带有源的jar drill-simple-mask-1.0-sources.jar 最后您必须在项目的resources文件夹中添加drill-module.conf文件以告诉Drill您的jar包含自定义函数。 如果您没有为功能设置特定的配置则可以将此文件保留为空。 一切准备就绪您现在可以打包和部署新功能只需打包并将Jars复制到Drill 3rd party文件夹中即可 $ DRILL_HOME / jars / 3rdparty其中$ DRILL_HOME是您的Drill安装文件夹。 mvn clean packagecp target/*.jar $DRILL_HOME/jars/3rdparty 重新开始练习。 跑 现在您应该可以在查询中使用您的函数了 SELECT MASK(first_name, * , 3) FIRST , MASK(last_name, #, 7) LAST FROM cp.employee.json LIMIT 5;
----------------------
| FIRST | LAST |
----------------------
| ***ri | ###### |
| ***rick | ####### |
| ***hael | ###### |
| ***a | #######ez |
| ***erta | ####### |
----------------------结论 在这个简单的项目中您学习了如何编写部署和使用自定义的Apache Drill Function。 现在您可以扩展它以创建自己的函数。 扩展Apache Drill使用自定义功能存储插件或格式时要记住的一件事是Drill运行时动态生成大量代码。 这意味着在编写和部署扩展时可能必须使用非常特定的模式。 使用我们的基本功能这意味着我们必须 部署类和源 使用完全合格的班级名称 使用值持有者类和辅助方法来操纵参数* 翻译自: https://www.javacodegeeks.com/2015/07/apache-drill-how-to-create-a-new-function.htmldrill apache