Hive自定义函数udf实例

合集下载

Hive进行UDF开发

Hive进行UDF开发

Hive进行UDF开发十分简单,此处所说UDF为Temporary的function,所以需要hive版本在0.4.0以上才可以。

Hive的UDF开发只需要重构UDF类的evaluate函数即可。

例:[java]view plaincopy1.package com.sohu.hive.udf;2.3.import org.apache.hadoop.hive.ql.exec.UDF;4.5.public class Md5 extends UDF {6.public String evaluate(String str) {7.8.try {9.10.return MD5Util.getMD5Str(str).substring(0, 7);11.12. } catch (Exception e) {13. e.printStackTrace();14.return str;15.16. }17.18. }19.}将该java文件编译成md5.jar[sql]view plaincopy1.hive> add jar md5.jar;2.3.hive> create temporary function md5as 'com.sohu.hive.udf.Md5';4.5.hive> select md5(url) from focuspvlog limit 2;6.7.hive> drop temporary function md5;注:1.md5为临时的函数,所以每次进入hive都需要add jar以及create temporary操作2.UDF只能实现一进一出的操作,如果需要实现多进一出,则需要实现UDAFhive 支持UDF,UDAF,UDTF,这几个让你使用hive 更加便捷。

UDFudf 就是一个自定义的function,输入一个或多个参数,返回一个返回值,类似substr/trim 之类。

genericudf 与 普通的udf 函数

genericudf 与 普通的udf 函数

genericudf 与普通的udf 函数标题:深入理解GenericUDF与普通UDF函数的区别与应用在大数据处理和分析中,用户定义的函数(User Defined Function,简称UDF)扮演着至关重要的角色。

它们允许开发者根据特定的需求定制数据处理逻辑,极大地提升了数据处理的灵活性和效率。

在Hadoop生态系统中,主要有两种类型的UDF:普通UDF和GenericUDF。

本文将详细解析这两种UDF的区别,并通过实例一步步展示其应用。

一、普通UDF普通UDF是Hive中最基本的自定义函数类型。

它主要用于处理单个数据行或列,并返回一个单一的结果。

普通UDF需要开发者实现evaluate()方法,该方法接受一个或多个参数,并返回一个结果。

以下是一个简单的普通UDF示例,该函数接收一个字符串参数并返回其长度:javaimport org.apache.hadoop.hive.ql.exec.UDF;public class StringLengthUDF extends UDF {public int evaluate(String str) {if (str == null) {return 0;}return str.length();}}在这个例子中,我们定义了一个名为StringLengthUDF的类,它继承了UDF基类。

然后我们实现了evaluate()方法,该方法接受一个字符串参数,并返回其长度。

二、GenericUDF相比于普通UDF,GenericUDF提供了更大的灵活性和可扩展性。

GenericUDF可以处理多种数据类型,并且可以返回复杂的数据结构。

在GenericUDF中,开发者需要实现initialize()、getReturnType()和evaluate()方法。

以下是一个简单的GenericUDF示例,该函数接收两个整数参数并返回它们的和:javaimport org.apache.hadoop.hive.ql.udf.generic.GenericUDF; importorg.apache.hadoop.hive.serde2.objectinspector.ObjectInspector; importorg.apache.hadoop.hive.serde2.objectinspector.primitive.Primitive ObjectInspectorFactory;importorg.apache.hadoop.hive.serde2.objectinspector.primitive.IntObjectI nspector;public class AddUDF extends GenericUDF {private IntObjectInspector intOI1;private IntObjectInspector intOI2;Overridepublic ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException {if (arguments.length != 2) {throw new UDFArgumentException("AddUDF accepts exactly 2 arguments");}if (!(arguments[0] instanceofIntObjectInspector) !(arguments[1] instanceof IntObjectInspector)) {throw new UDFArgumentException("Both arguments should be of int type");}this.intOI1 = (IntObjectInspector) arguments[0];this.intOI2 = (IntObjectInspector) arguments[1];returnPrimitiveObjectInspectorFactory.javaIntObjectInspector;}Overridepublic Object evaluate(DeferredObject[] arguments) throws HiveException {int arg1 = intOI1.get(arguments[0].get());int arg2 = intOI2.get(arguments[1].get());return arg1 + arg2;}Overridepublic String getDisplayString(String[] children) {return "add(" + children[0] + ", " + children[1] + ")";}}在这个例子中,我们定义了一个名为AddUDF的类,它继承了GenericUDF基类。

hive项目实训案例

hive项目实训案例

hive项目实训案例Hive是一个基于Hadoop的数据仓库工具,用于处理和分析大数据。

以下是几个Hive项目实训案例,可以帮助你深入了解Hive的应用和实践:1. 数据仓库建模在这个案例中,你将使用Hive构建一个数据仓库模型,其中包括事实表、维度表和桥接表。

你可以使用一个现有的数据集,如电商交易数据,将其导入到Hive中,并使用Hive的DDL语句创建表和分区。

然后,你可以使用Hive的SQL查询语句进行数据分析,例如计算销售额、订单数量等指标。

2. 数据清洗和转换在这个案例中,你将使用Hive进行数据清洗和转换。

你可以使用Hive的内置函数和UDF(用户自定义函数)对数据进行处理,例如去除重复记录、填充缺失值、转换数据类型等。

然后,你可以将处理后的数据导出到另一个数据存储系统,例如关系型数据库或数据湖。

3. 数据分析和可视化在这个案例中,你将使用Hive进行数据分析和可视化。

你可以使用Hive的SQL查询语句对数据进行聚合、过滤和连接操作,例如计算销售额的分布、找出购买最多的商品等。

然后,你可以将分析结果导出到Excel或其他可视化工具中进行展示。

4. 数据挖掘和机器学习在这个案例中,你将使用Hive进行数据挖掘和机器学习。

你可以使用Hive 的MLlib库进行分类、聚类、回归等机器学习算法的实现。

然后,你可以将训练好的模型导出到另一个系统进行部署和应用。

以上是几个Hive项目实训案例,可以帮助你深入了解Hive的应用和实践。

通过这些案例的学习和实践,你可以更好地掌握Hive的使用方法和技巧,提高你的大数据处理和分析能力。

hive创建自定义函数

hive创建自定义函数

hive默认的函数并不是太完整,以后我们使用的使用肯定需要自己补充一些。

下面这个例子是个简单的测试,关于自定义函数的。

函数代码package com.example.hive.udf;import org.apache.hadoop.hive.ql.exec.UDF;import org.apache.hadoop.io.Text;public final class Lower extends UDF {public Text evaluate(final Text s) {if (s == null) { return null; }return new Text(s.toString().toLowerCase());}}打包javac -d Lower Lower.javajar -cvf Lower.jar -C Lower/ .在hive中添加包hive> add jar /home/hjl/sunwg/Lower.jar;Added /home/hjl/sunwg/Lower.jar to class path在hive中创建函数hive> create temporary function my_lower as …com.example.hive.udf.Lower‟;OKTime taken: 0.407 seconds使用函数hive> select my_lower(name) from test10;上面介绍了HIVE中的自定义函数,有一些函数是比较基础的,公用的,每次都要create temporary function不免太麻烦了。

这样的基础函数需要直接集成到hive中去,避免每次都要创建。

1,添加函数文件$HIVE_HOME/src/ql/src/java/org/apache/hadoop/hive/ql/udf/UDFSunwg.javapackage org.apache.hadoop.hive.ql.udf;import org.apache.hadoop.hive.ql.exec.Description;import org.apache.hadoop.hive.ql.exec.UDF;import org.apache.hadoop.io.IntWritable;import org.apache.hadoop.io.Text;public final class UDFSunwg extends UDF {public Text evaluate(final Text s) {if (s == null) { return null; }return new Text(s.toString().concat(“sunwg”).toLowerCase());}}2,将函数sunwg注册到hive的函数列表中修改$HIVE_HOME/src/ql/src/java/org/apache/hadoop/hive/ql/exec/FunctionRegistry.java 文件import org.apache.hadoop.hive.ql.udf.UDFSunwg;registerUDF(“sunwg”, UDFSunwg.class,false);3,测试函数sunwghive> select sunwg(“abc”) from sunwg00 limit 1;Total MapReduce jobs = 1Launching Job 1 out of 1Number of reduce tasks is set to 0 since there‟s no reduce operatorStarting Job = job_201104091858_381437, Tracking URL =http://hdpjt:50030/jobdetails.jsp?jobid=job_201104091858_381437Kill Command = /home/dwapp/hadoop/bin/../bin/hadoopjob -Dmapred.job.tracker=hdpjt:9001 -kill job_201104091858_3814372011-04-21 16:01:28,733 Stage-1 map = 0%, reduce = 0%2011-04-21 16:01:34,123 Stage-1 map = 50%, reduce = 0%2011-04-21 16:01:35,543 Stage-1 map = 100%, reduce = 0%Ended Job = job_201104091858_381437OKabcsunwgTime taken: 48.53 seconds总结:在hive中添加函数是如此的简单,建议将公共的基础函数添加到hive中,而一些个性化的函数还是创建临时函数create temporary function IS_DATE as 'com.ruyicai.hive.udf.IsDate';create temporary function nvl as 'com.ruyicai.hive.udf.Nvl';add jar /root/isdate-0.0.1-SNAPSHOT.jar;add jar /root/nvl-0.0.1-SNAPSHOT.jar;。

自定义udf函数解析嵌套json数组

自定义udf函数解析嵌套json数组

自定义udf函数解析嵌套json数组在进行数据分析时,我们经常会遇到一些嵌套的JSON数组。

如果我们想要对这些数据进行分析,并且使用SQL语言进行查询和分析,我们通常需要自定义UDF函数来解析这些嵌套的JSON数组。

首先,我们需要了解UDF函数是什么。

UDF函数是一种用户自定义的函数,可以在SQL中使用。

它可以接收一个或多个参数,并返回一个结果。

在解析嵌套的JSON数组时,我们需要使用UDF函数来将JSON数组转换为关系型数据。

我们可以使用Python或Java等编程语言来编写UDF函数。

例如,在Python中,我们可以使用json模块来解析JSON数据。

下面是一个示例UDF函数,它可以将嵌套的JSON数组解析为关系型数据:```pythonimport jsondef parse_json_array(json_str):json_obj = json.loads(json_str)result = []for obj in json_obj:row = {}for key, value in obj.items():if isinstance(value, list):row[key] = json.dumps(value)else:row[key] = valueresult.append(row)return json.dumps(result)```这个函数接收一个JSON字符串作为参数,并将其解析为一个列表。

然后,它遍历列表中的每个对象,并将其转换为一个字典,其中键是JSON属性的名称,值是JSON属性的值。

如果属性的值是一个JSON数组,它会将其转换为一个字符串,并将其放入字典中。

最后,它将所有的字典放入一个列表中,并将整个列表转换为一个JSON字符串。

在使用这个UDF函数时,我们需要将其注册到SQL中。

例如,在Hive中,我们可以使用以下命令来注册UDF:```sqlADD JAR /path/to/udf.jar;CREATE TEMPORARY FUNCTION parse_json_array AS'com.example.udf.ParseJsonArray';```在注册了UDF函数之后,我们可以在SQL中使用它来解析嵌套的JSON数组。

hive3 udf函数编写

hive3 udf函数编写

hive3 udf函数编写Hive是一个用于数据仓库和大数据分析的开源数据仓库工具,它是基于Hadoop的一个数据仓库基础架构,提供类似于SQL的查询语言HiveQL,使得开发人员可以使用常见的SQL语言来处理分布式存储中的大数据。

在Hive中,用户自定义函数(User-Defined Functions,UDFs)可以用于扩展HiveQL语言的功能,使得开发人员可以根据自己的需求编写自定义的函数。

本文将讨论在Hive3中编写UDF函数的方法和步骤。

首先,我们需要了解Hive的UDF函数的分类。

Hive的UDF函数可以分为以下几类:1. 标量函数(Scalar Functions):接受一些输入参数,并返回一个单一的输出结果。

例如,将一个字符串转换为大写或者将两个数字相加。

2. 聚合函数(Aggregate Functions):接受一组输入值,并返回一个聚合结果。

例如,计算平均值或求和。

3. 表生成函数(Table Generating Functions):接受一些输入参数,并生成一个输出表。

接下来,我们将以一个简单的示例来演示如何编写Hive3的UDF函数。

假设我们有一个包含员工姓名和薪水的表格,我们想要创建一个函数来计算员工薪水的增长百分比。

首先,我们需要创建一个新的Java类来实现我们的UDF函数。

这个类需要继承Hive的UDF类,并且重写evaluate()方法。

```import org.apache.hadoop.hive.ql.exec.Description;import org.apache.hadoop.hive.ql.exec.UDF;import org.apache.hadoop.hive.ql.udf.UDFType;@Description(name = "salary_growth_percentage",value = "Calculates the growth percentage of an employee's salary",extended = "SELECT salary_growth_percentage(salary) FROM employees")@UDFType(deterministic = true, stateful = false)public class SalaryGrowthPercentage extends UDF {public Double evaluate(Double currentSalary, Double previousSalary) {if (currentSalary == null || previousSalary == null) {return null;}double growthPercentage = (currentSalary - previousSalary) / previousSalary * 100;return growthPercentage;}}```在上述代码中,我们创建了一个名为SalaryGrowthPercentage的类,它继承自Hive的UDF类。

hive udf函数例子

hive udf函数例子

hive udf函数例子Hive中的UDF(User-Defined Functions)是用户自定义的函数,用于对Hive中的数据进行自定义操作和处理。

UDF可以是一元函数(接受一个输入参数并返回一个值)或者多元函数(接受多个输入参数并返回一个值)。

下面我将举例说明Hive中UDF函数的用法。

首先,我们可以创建一个简单的UDF函数来实现字符串的反转。

假设我们需要一个UDF函数来反转给定的字符串,我们可以按照以下步骤创建UDF函数:1. 创建一个Java类,实现Hive的UDF接口,并重写evaluate方法来定义函数的逻辑。

以下是一个简单的示例代码:java.import org.apache.hadoop.hive.ql.exec.UDF;import org.apache.hadoop.io.Text;public class ReverseStringUDF extends UDF {。

public Text evaluate(Text input) {。

if (input == null) return null;return new Text(newStringBuilder(input.toString()).reverse().toString());}。

}。

2. 编译这个Java类并将生成的JAR文件添加到Hive的classpath中。

3. 在Hive中注册这个UDF函数,例如:sql.ADD JAR /path/to/your/jar/udf.jar;CREATE TEMPORARY FUNCTION reverse_string AS'ReverseStringUDF';4. 现在我们就可以在Hive中使用这个UDF函数了,例如:sql.SELECT reverse_string('hello') FROM your_table;这样就可以实现对字符串进行反转的操作。

自定义udf函数解析嵌套json数组

自定义udf函数解析嵌套json数组

自定义udf函数解析嵌套json数组如何使用自定义UDF函数解析嵌套JSON数组为标题在数据处理中,JSON格式的数据已经成为了一种非常常见的数据格式。

而在JSON数据中,有时候会出现嵌套的数组,这就给数据的处理带来了一定的难度。

本文将介绍如何使用自定义UDF函数解析嵌套JSON数组为标题。

我们需要了解什么是UDF函数。

UDF函数是用户自定义函数的缩写,是一种自定义函数,可以根据自己的需求编写函数,以实现特定的功能。

在Hive中,UDF函数可以用来处理各种数据类型,包括字符串、数字、日期等。

接下来,我们需要了解如何解析嵌套JSON数组。

在Hive中,我们可以使用get_json_object函数来解析JSON数据。

但是,当JSON数据中存在嵌套的数组时,get_json_object函数就无法解析了。

这时,我们就需要使用自定义UDF函数来解析嵌套的JSON数组。

下面是一个示例JSON数据:{"name": "John","age": 30,"address": {"street": "123 Main St","city": "New York","state": "NY","zip": "10001"},"phone_numbers": [{"type": "home","number": "555-555-1234"},{"type": "work","number": "555-555-5678"}]}在这个JSON数据中,phone_numbers是一个嵌套的数组。

Hive自定义函数(UDF、UDAF)

Hive自定义函数(UDF、UDAF)

Hive⾃定义函数(UDF、UDAF)当Hive提供的内置函数⽆法满⾜你的业务处理需要时,此时就可以考虑使⽤⽤户⾃定义函数。

###UDF⽤户⾃定义函数(user defined function)–针对单条记录。

创建函数流程1、⾃定义⼀个Java类2、继承UDF类3、重写evaluate⽅法4、打成jar包6、在hive执⾏add jar⽅法7、在hive执⾏创建模板函数8、hql中使⽤Demo01:⾃定义⼀个Java类package UDFDemo;import org.apache.hadoop.hive.ql.exec.UDF;import org.apache.hadoop.io.Text;public class UDFTest extends UDF{public boolean evaluate(){return true;}public boolean evaluate(int b){//int b=Integer.parseInt(a);if(b<0){return false;}if(b%2==0){return true;}else {return false;}}public boolean evaluate(String a){int b=Integer.parseInt(a);if(b<0){return false;}if(b%2==0){return true;}else {return false;}}public boolean evaluate(Text a){int b=Integer.parseInt(a.toString());if(b<0){return false;}if(b%2==0){if(b%2==0){return true;}else {return false;}}public boolean evaluate(Text t1,Text t2){//public boolean evaluate(String t1, String t2){if(t1==null || t2 ==null){return false;}double d1 = Double.parseDouble(t1.toString());double d2 = Double.parseDouble(t2.toString());/* double d1 = Double.parseDouble(t1);double d2 = Double.parseDouble(t2);*/if(d1>d2){return true;}else{return false;}}public boolean evaluate(String t1, String t2){if(t1==null || t2 ==null){return false;}double d1 = Double.parseDouble(t1);double d2 = Double.parseDouble(t2);if(d1>d2){return true;}else{return false;}}}打成jar包UDFTest.jar在hive执⾏add jar⽅法在hive创建⼀个bigthan的函数,引⼊的类是UDF.UDFTestadd jar /liguodong/UDFTest.jar;create temporary function bigthan as 'UDFDemo.UDFTest';select no,num,bigthan(no,num) from testudf;###UDAFUDAF(user defined aggregation function)⽤户⾃定义聚合函数,针对记录集合开发UDAF通⽤有两个步骤第⼀个是编写resolver类,resolver负责类型检查,操作符重载。

Hive自定义UDF函数

Hive自定义UDF函数

Hive⾃定义UDF函数Hive的SQL可以通过⽤户定义的函数(UDF),⽤户定义的聚合(UDAF)和⽤户定义的表函数(UDTF)进⾏扩展。

当Hive提供的内置函数⽆法满⾜你的业务处理需要时,此时就可以考虑使⽤⽤户⾃定义函数(UDF)。

UDF、UDAF、UDTF的区别:UDF(User-Defined-Function)⼀进⼀出UDAF(User-Defined Aggregation Funcation)聚集函数,多进⼀出UDTF(User-Defined Table-Generating Functions)⼀进多出,如lateral view explore()⽤户⾃定义函数(user defined function),针对单条记录。

编写⼀个UDF,需要继承UDF类,并实现evaluate()函数。

在查询执⾏过程中,查询中对应的每个应⽤到这个函数的地⽅都会对这个类进⾏实例化。

对于每⾏输⼊都会调⽤到evaluate()函数。

⽽evaluate()函数处理的值会返回给Hive。

同时⽤户是可以重载evaluate⽅法的。

Hive会像Java的⽅法重载⼀样,⾃动选择匹配的⽅法.⼀、应⽤案例1)全⾓转半⾓package com.sjck.hive.udf;import ng.StringUtils;import org.apache.hadoop.hive.ql.exec.UDF;/*** 全⾓转半⾓* @author Administrator**/public class ToSingleByte extends UDF {public static String evaluate(String val) {if(StringUtils.isNotBlank(val)){char c[] = val.toCharArray();for (int i = 0; i < c.length; i++) {if (c[i] == '\u3000') {c[i] = ' ';} else if (c[i] > '\uFF00' && c[i] < '\uFF5F') {c[i] = (char) (c[i] - 65248);}}String returnString = new String(c);return returnString;}return "";}}View Code2)⾝份证信息验证package com.sjck.hive.udf.util;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Calendar;import java.util.Date;import org.slf4j.Logger;import org.slf4j.LoggerFactory;/*** <p>* ⾝份证合法性校验* --15位⾝份证号码:第7、8位为出⽣年份(两位数),第9、10位为出⽣⽉份,第11、12位代表出⽣⽇期,第15位代表性别,奇数为男,偶数为⼥。

HIVEudf实例

HIVEudf实例

HIVEudf实例本例中udf来⾃《hive编程指南》其中13章⾃定义函数中⼀个例⼦。

按照步骤,第⼀步,建⽴⼀个项⽬,创建 GenericUDFNvl 类。

/*** 不能接受第⼀个参数为null的情况* 测试过,不是很好⽤*/package hive.udf;import org.apache.hadoop.hive.ql.exec.Description;import org.apache.hadoop.hive.ql.exec.UDFArgumentException;import org.apache.hadoop.hive.ql.exec.UDFArgumentLengthException;import org.apache.hadoop.hive.ql.exec.UDFArgumentTypeException;import org.apache.hadoop.hive.ql.metadata.HiveException;import org.apache.hadoop.hive.ql.udf.generic.GenericUDF;import org.apache.hadoop.hive.ql.udf.generic.GenericUDFUtils;import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;@Description(name = "nvl",value = "_FUNC_(value,default_value) - Returns default value if value is nul else returns value",extended = "Example:\n> SELECT _FUNC_(NULL, 'bla') FROM src LIMIT 1;")public class GenericUDFNvl extends GenericUDF {private GenericUDFUtils.ReturnObjectInspectorResolver returnOIResolver;private ObjectInspector[] argumentOIs;@Overridepublic ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException {argumentOIs = arguments;if (arguments.length != 2) {throw new UDFArgumentLengthException("The operator 'NVL' accepts 2 arguments.");}returnOIResolver = new GenericUDFUtils.ReturnObjectInspectorResolver(true);if (!(returnOIResolver.update(arguments[0]) && returnOIResolver.update(arguments[1]))) {throw new UDFArgumentTypeException(2,"THe 1st and 2nd args of function NVL should have the same type, "+ "but they are different: \"" + arguments[0].getTypeName()+ "\" and \"" + arguments[1].getTypeName() + "\"");}return returnOIResolver.get();}@Overridepublic Object evaluate(DeferredObject[] arguments) throws HiveException {Object retVal = returnOIResolver.convertIfNecessary("", argumentOIs[0]);//if (retVal == null) {retVal = returnOIResolver.convertIfNecessary(arguments[1], argumentOIs[1]);//}return retVal;}@Overridepublic String getDisplayString(String[] children) {StringBuilder sb = new StringBuilder();sb.append("if ");sb.append(children[0]);sb.append(" is null ");sb.append("returns");sb.append(children[1]);return sb.toString();}}创建完成之后,在项⽬中点右键->Export->JAR file,再下⼀步中选中刚刚创建的这个⽂件,将⽂件导出为.jar⽂件。

hive自增函数

hive自增函数

hive自增函数Hive自增函数是一种用于自动生成唯一值的函数。

在Hive中,可以使用自增函数在表中生成一个递增的序列值。

Hive自增函数是通过使用Hive内置的UDF(用户自定义函数)和UDAF(用户自定义聚合函数)来实现的。

下面是几种常用的Hive自增函数的示例:1.使用UDF实现自增函数```sqlCREATE TABLE my_tableid INT,name STRING--创建自定义UDF-- 使用自增函数生成递增的idINSERT INTO TABLE my_table SELECT get_next_id(, 'John';INSERT INTO TABLE my_table SELECT get_next_id(, 'Alice';```上面的示例中,我们先创建了一个包含id和name字段的表my_table。

然后,我们创建了一个自定义的UDF get_next_id,该UDF负责生成下一个递增的id。

最后,我们使用自增函数get_next_id(在插入数据时生成递增的id。

2.使用UDAF实现自增函数```sqlCREATE TABLE my_tableid INT,name STRING--创建自定义UDAF-- 使用自增函数生成递增的idINSERT INTO TABLE my_tableSELECT get_next_id(, 'John'FROM (SELECT NULL) temp;INSERT INTO TABLE my_tableSELECT get_next_id(, 'Alice'FROM (SELECT NULL) temp;```上面的示例中,我们先创建了一个包含id和name字段的表my_table。

然后,我们创建了一个临时的自定义UDAF get_next_id,该UDAF负责生成下一个递增的id。

Hive自定义函数UDF

Hive自定义函数UDF

Hive自定义函数UDF在使用hive的时候,hive本身自带的函数不足以满足于我们需求的情况下,我们可以自定义满足我们需求的函数。

一、hive自定义函数步骤:1、继承org.apache.hadoop.hive.ql.exec.UDF;2、写固定的evaluate()方法。

这个方法名字是固定的。

注意:evaluate方法支持重载。

二、实例演示1、代码package com.hive.test;import org.apache.hadoop.hive.ql.exec.UDF;public class HiveUdf extends UDF{public String evaluate(int num){if(num>1000){return "very good";}else if(num>500){return "good";}else {return "bad";}}}2、将此代码打成jar包并上传linux3、准备测试数据[root@cmaster test]# vim num.txt4、创建表并且导入数据hive> create table mytest(id int) row format delimited fields terminated by ' ';hive> load data local inpath '/test/num.txt' into table mytest;5、将jar加载到hive中hive> add jar /test/hiveUdf_jar/hive_test.jar> ;6、创建一个临时函数指向上边编译的类hive> create temporary function myF as 'com.hive.test.HiveUdf';7、可以调用这个函数了hive> select myF(id) from mytest;OKvery goodgoodgoodbadTime taken: 1.742 seconds, Fetched: 4 row(s)8、调用完函数可以删除hive> drop temporary function myF;注意:查询hive所有函数使用 show functions hive> show functions;。

hive自定义UDF编写函数

hive自定义UDF编写函数

1.创建一个类继承GenericUDF或者UDF类,在类中实现自定义函数的逻辑,此例是继承GenericUDF类。

GenericUDF实现比较复杂,需要先继承GenericUDF。

这个API需要操作Object Inspectors,并且要对接收的参数类型和数量进行检查。

GenericUDF需要实现以下三个方法://这个方法只调用一次,并且在evaluate()方法之前调用。

该方法接受的参数是一个ObjectInspectors数组。

该方法检查接受正确的参数类型和参数个数。

abstract ObjectInspector initialize(ObjectInspector[] arguments);//这个方法类似UDF的evaluate()方法。

它处理真实的参数,并返回最终结果。

abstract Object evaluate(GenericUDF.DeferredObject[] arguments);//这个方法用于当实现的GenericUDF出错的时候,打印出提示信息。

而提示信息就是你实现该方法最后返回的字符串。

abstract String getDisplayString(String[] children);2.此处是重新实现hive中add_months函数,实现和mysql中添加月份一样的效果(date_add(CURDATE(),INTERVAL 1 MONTH)),此处需要引入两个jar包:hadoop-common-2.7.3.jar,hive-exec-1.2.1.jar,项目结构如下图:需要在项目中添加一个MANIFEST.MF文件,定义主类和关联的jar包,内容如下:说明:Class-Path需要指定依赖的第三方jar包的存储位置3.打包过程如下:勾选要打包的文件,指定生成的jar包名和存储位置直接Next选择前面项目中添加的MANIFEST.MF文件,如下图最后直接点击Finish即可4.将jar包上传到hive上,注册自定义函数临时函数先将上面生成的jar放到服务器上某个位置,然后进入hive客户端,执行以下命令,注册一个临时函数:add jar /home/...(省略).../bigdata-udf-mysqladdmonths.jar;create temporary function mysql_add_months as 'com.xxx.udf.MysqlAddMonths';select mysql_add_months('2018-02-28',1);永久函数在hdfs上创建一个目录然后把生成的jar包和依赖的两个jar包上传上去,结果如下图1.执行hdfs命令建目录(切换到hdfs用户):hadoop dfs -mkdir /apps/hive/udf_libs2.把jar包先放到一个临时目录下,进入目录,执行hadoop命令,然后删除目录hadoop dfs -put *.jar在进入hive客户端,执行创建函数命令create function mysql_add_months as 'com.xxx.udf.MysqlAddMonths' USING JAR 'hdfs://xxxcluster/apps/hive/udf_libs/bigdata-udf-mysqladdmonths.jar'使用示例:select mysql_add_months('2018-02-28',1);。

hive中简单的udf函数编写

hive中简单的udf函数编写

hive中简单的udf函数编写1.注册函数,使⽤using jar⽅式在hdfs上引⽤udf库。

$hive>create function formattime as'com.bigdata.udf.FormatTimeUDF' using jar 'hdfs://hadoop01/app/app-logs-hive-1.0-SNAPSHOT.jar';2.注销函数,只需要删除mysql的hive数据记录即可。

delete from func_ru ;delete from funcs ;show funcyions;desc formatted function substring;2.udf函数获取天开始⼀些简单⽅法@Description(name = "udf_getdaybegin",value = "getdaybegin",extended = "getdaybegin() ;\r\n"+ " getdaybegin(2) \r\n"+ " getdaybegin('2017/06/29 01:02:03') \r\n"+ " getdaybegin('2017/06/29 01:02:03',2) \r\n"+ " getdaybegin(date_obj) \r\n"+ " getdaybegin(date_obj,2)")public class DayBeginUDF extends UDF {/*** 计算现在的起始时刻(毫秒数)*/public long evaluate() throws ParseException {return evaluate(new Date());}/*** 指定天偏移量*/public long evaluate(int offset) throws ParseException {return evaluate(DateUtil.getDayBeginTime(new Date(), offset));}/*** 计算某天的开始时刻(毫秒数)*/public long evaluate(Date d) throws ParseException {return DateUtil.getDayBeginTime(d).getTime();}/*** 计算某天的开始时刻(毫秒数)*/public long evaluate(Date d, int offset) throws ParseException {return DateUtil.getDayBeginTime(d, offset).getTime();}/*** 计算某天的起始时刻(毫秒数)*/public long evaluate(String dateStr) throws ParseException {SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");Date d = sdf.parse(dateStr);return evaluate(d);}/*** 计算某天的起始时刻(毫秒数)*/public long evaluate(String dateStr, int offset) throws ParseException {SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");Date d = sdf.parse(dateStr);return DateUtil.getDayBeginTime(d, offset).getTime();}/*** 计算某天的起始时刻(毫秒数)*/public long evaluate(String dateStr, String fmt) throws ParseException {SimpleDateFormat sdf = new SimpleDateFormat(fmt);Date d = sdf.parse(dateStr);return DateUtil.getDayBeginTime(d).getTime();}/*** 计算某天的起始时刻(毫秒数)*/public long evaluate(String dateStr, String fmt, int offset) throws ParseException {SimpleDateFormat sdf = new SimpleDateFormat(fmt);Date d = sdf.parse(dateStr);return DateUtil.getDayBeginTime(d, offset).getTime();}}。

大数据javahiveudf函数的示例代码(手机号码脱敏)

大数据javahiveudf函数的示例代码(手机号码脱敏)

⼤数据javahiveudf函数的⽰例代码(⼿机号码脱敏)Hive UDFHive UDF 函数1 POM ⽂件2.UDF 函数3 利⽤idea打包4 添加hive udf函数4.1 上传jar包到集群4.2 修改集群hdfs⽂件权限4.3 注册UDF4.4 使⽤UDF Hive UDF 函数1 POM ⽂件<?xml version="1.0" encoding="UTF-8"?><project xmlns="/POM/4.0.0"xmlns:xsi="/2001/XMLSchema-instance"xsi:schemaLocation="/POM/4.0.0 /xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>填写⾃⼰的组织名称</groupId><artifactId>udf</artifactId><version>1.0-SNAPSHOT</version><properties><project.build.sourceEncoding>UTF8</project.build.sourceEncoding><!--Hadoop版本更改成⾃⼰的版本--><hadoop.version>2.6.0-cdh5.13.3</hadoop.version><hive.version>1.1.0-cdh5.13.3</hive.version></properties><repositories><!--加⼊Hadoop原⽣态的maven仓库的地址--><repository><id>Apache Hadoop</id><name>Apache Hadoop</name><url>https:///maven2/</url></repository><!--加⼊cdh的maven仓库的地址--><repository><id>cloudera</id><name>cloudera</name><url>https:///artifactory/cloudera-repos/</url></repository></repositories><dependencies><!--添加hadoop依赖--><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-common</artifactId><version>${hadoop.version}</version></dependency><!--添加hive依赖--><dependency><groupId>org.apache.hive</groupId><artifactId>hive-exec</artifactId><version>${hive.version}</version></dependency></dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><source>1.8</source><target>1.8</target></configuration></plugin><plugin><artifactId>maven-assembly-plugin</artifactId><configuration><!--这部分可有可⽆,加上的话则直接⽣成可运⾏jar包--><!--<archive>--><!--<manifest>--><!--<mainClass>填写⾃⼰的组织名称.PhoneUnlookUdf</mainClass>--><!--</manifest>--><!--</archive>--><descriptorRefs><descriptorRef>jar-with-dependencies</descriptorRef></descriptorRefs></configuration><executions><execution><id>make-assembly</id><phase>package</phase><goals><goal>single</goal></goals></execution></executions></plugin></plugins></build></project>2.UDF 函数package 填写⾃⼰的组织名称;import org.apache.hadoop.hive.ql.exec.Description;import org.apache.hadoop.hive.ql.exec.UDF;// 上传udf jar到集群 hdfs dfs -put udf-1.0-SNAPSHOT-jar-with-dependencies.jar /data/data_coe/data_asset/prod/db/tmp/udf/// 修改⽂件权限 hdfs dfs -chmod -R 777 hdfs://idc-nn/data/data_coe/data_asset/prod/db/tmp/udf///注册udf函数 create function tmp.pul as '填写⾃⼰的组织名称.PhoneUnlookUdf' using jar 'hdfs://idc-nn/data/data_coe/data_asset/prod/db/tmp/udf/udf-1.0-SNAPSHOT-jar-with-dependencies.jar public class PhoneUnlookUdf extends UDF {//重写evaluate⽅法public String evaluate(String phone){if (phone.length() == 11){String res = phone.substring(0, 3) + "****" + phone.substring(7, phone.length());System.out.println(res);return res;} else {return phone;}}}3 利⽤idea打包先点clean,在点package4 添加hive udf函数集群的某些问题,不能直接通过添加服务器上本地⽂件到hive增加udf;需要将⽂件上传到hdfs,然后定义udf函数。

Hive自定义UDTF函数

Hive自定义UDTF函数

Hive⾃定义UDTF函数UDTF(User-Defined Table-Generating Functions)⼀进多出,如lateral view explore()实现⽅法:1)继承org.apache.hadoop.hive.ql.udf.generic.GenericUDTF2)重写initialize、process、close⽅法UDTF⾸先会调⽤initialize⽅法,此⽅法返回UDTF的返回⾏的信息(返回个数,类型,名称)。

初始化完成后,会调⽤process⽅法,对传⼊的参数进⾏处理,可以通过forword()⽅法把结果返回。

最后close()⽅法调⽤,对需要清理的⽅法进⾏清理应⽤案例需求:使⽤⾃定义UDTF函数获取两个时间之间的时间列表package com.sjck.hive.udf;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.ArrayList;import java.util.Calendar;import java.util.Date;import org.apache.hadoop.hive.ql.exec.UDFArgumentException;import org.apache.hadoop.hive.ql.exec.UDFArgumentLengthException;import org.apache.hadoop.hive.ql.metadata.HiveException;import org.apache.hadoop.hive.ql.udf.generic.GenericUDTF;import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorFactory;import org.apache.hadoop.hive.serde2.objectinspector.StructObjectInspector;import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory;public class DateMap extends GenericUDTF {@Overridepublic void close() throws HiveException {}@Overridepublic StructObjectInspector initialize(ObjectInspector[] args) throws UDFArgumentException {if (args.length != 2) {throw new UDFArgumentLengthException("DateMap takes only two argument");}ArrayList<String> fieldNames = new ArrayList<String>();ArrayList<ObjectInspector> fieldOIs = new ArrayList<ObjectInspector>();fieldNames.add("begin_date"); //指定输出参数名称fieldOIs.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);fieldNames.add("end_date");fieldOIs.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);return ObjectInspectorFactory.getStandardStructObjectInspector(fieldNames, fieldOIs);}@Overridepublic void process(Object[] args) throws HiveException {try {String begin = String.valueOf(args[0]);String end = String.valueOf(args[1]);SimpleDateFormat timeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");int days = (int) (dateFormat.parse(end).getTime() - dateFormat.parse(begin).getTime())/ (60 * 60 * 24 * 1000);Date startDate = timeFormat.parse(begin);Date endDate = timeFormat.parse(end);Calendar ecalendar = Calendar.getInstance();ecalendar.setTime(startDate);Date d1 = startDate;Date d2 = null;if(days==0){d2=endDate;}else{ecalendar.add(Calendar.DATE, 1);ecalendar.set(Calendar.HOUR_OF_DAY, 0);ecalendar.set(Calendar.MINUTE, 0);ecalendar.set(Calendar.SECOND, 0);d2=ecalendar.getTime();}String datas[][] = new String[days + 1][2];datas[0][0] = timeFormat.format(d1);datas[0][1] = timeFormat.format(d2);for (int i = 1; i < days + 1; i++) {d1 = d2;ecalendar.add(Calendar.DATE, 1);d2 = ecalendar.getTime();if (d2.after(endDate)) {d2 = endDate;}datas[i][0] = timeFormat.format(d1);datas[i][1] = timeFormat.format(d2);}for (int i = 0; i < datas.length; i++) {String[] s = new String[2];s[0] = datas[i][0];s[1] = datas[i][1];forward(s);}} catch (ParseException e) {e.printStackTrace();}}}将代码打成jar包上传到服务器上,我这边是上传到hdfs上的hadoop fs -put hive-udf.jar /user/hive/udf声明函数create function datemap AS 'com.sjck.hive.udf.DateMap' using jar 'hdfs://nameservice1/user/hive/udf/hive-udf.jar'; 使⽤⽅式⼀:直接放在select后⾯看下使⽤到表结构select * from bst_bas_driver_info_work_time where id='2440780' //看看选择的⼀条数据使⽤datemap函数获取开始时间-结束时间中间的时间(按天展开)select datemap(date_format(t.work_start_time, 'yyyy-MM-dd HH:mm:ss'),date_format(t.work_end_time, 'yyyy-MM-dd HH:mm:ss')) as (begin_date,end_date) frombst_bas_driver_info_work_time twhere id='2440780'注意:1)不可以添加其他字段使⽤:select datemap(date_format(t.work_start_time, 'yyyy-MM-dd HH:mm:ss'),date_format(t.work_end_time, 'yyyy-MM-dd HH:mm:ss')) as (begin_date,end_date) frombst_bas_driver_info_work_time t where id='2440780'2)不可以嵌套调⽤:select datemap(datemap(xx,xxx),datemap(xx,xxx)) from bst_bas_driver_info_work_time3)不可以和group by/cluster by/distribute by/sort by⼀起使⽤:select datemap(xx,xxx)as (begin_date,end_date) from bst_bas_driver_info_work_time group by begin_date, end_date⽅式⼆:和lateral view⼀起使⽤select work_start_time as start_date,work_end_time as end_date,t.mid_start_date,t.mid_end_datefrom bst_bas_driver_info_work_time lateral view datemap(date_format(work_start_time, 'yyyy-MM-dd HH:mm:ss'), date_format(work_end_time, 'yyyy-MM-dd HH:mm:ss')) t as mid_start_date, mid_end_datewhere id in ('2440780') 其实这个功能⽤posexplode也可以完成,看下代码:效果⼀样,只不过中间逻辑⾃⼰还得单独做处理下,代码参考我的另⼀篇这⾥重点在于UDTF⾃定义函数的实现。

Spark(Hive)SQL中UDF的使用(Python)

Spark(Hive)SQL中UDF的使用(Python)

Spark(Hive)SQL中UDF的使⽤(Python)相对于使⽤MapReduce或者Spark Application的⽅式进⾏数据分析,使⽤Hive SQL或Spark SQL能为我们省去不少的代码⼯作量,⽽Hive SQL或Spark SQL本⾝内置的各类UDF也为我们的数据处理提供了不少便利的⼯具,当这些内置的UDF不能满⾜于我们的需要时,Hive SQL或Spark SQL还为我们提供了⾃定义UDF的相关接⼝,⽅便我们根据⾃⼰的需求进⾏扩展。

在Hive的世界⾥使⽤⾃定义UDF的过程是⽐较复杂的。

我们需要根据需求使⽤Java语⾔开发相应的UDF(UDAF、UDTF),然后将UDF的代码及其依赖编译打包为Jar,使⽤⽅法有两种:(1)临时函数在⼀次会话(Session)中使⽤如下语句创建临时函数:ADD JAR /run/jar/udf_test.jar;CREATE TEMPORARY FUNCTION my_add AS 'com.hive.udf.Add';这种⽅式有⼀个缺点:每⼀次会话过程中使⽤函数时都需要创建,⽽且仅在当前会话中有效。

(2)永久函数这个特性需要⾼版本的Hive⽀持,它的好处是可以将UDF Jar存放⾄HDFS,函数仅需要创建⼀次即可以永久使⽤,如下:CREATE FUNCTION func.ipToLocationBySina AS 'com.sina.dip.hive.function.IPToLocationBySina' USING JAR 'hdfs://dip.cdh5.dev:8020/user/hdfs/func/location.jar';虽然永久函数相对于临时函数有⼀定优势,但Java语⾔的开发门槛很⼤程度上妨碍了UDF在实际数据分析过程中使⽤,毕竟我们的数据分析师多数是以Python、SQL为主要分析⼯具的,每⼀次UDF的开发都需要⼯程师的参与,开发效率与应⽤效果都是不是很好(可能需要频繁更新UDF的问题),PySpark的出现确很好地解决了这个问题:它可以⾮常⽅便地将⼀个普通的Python函数注册为⼀个UDF。

2.13Hive中自带Function使用及自定义UDF编程

2.13Hive中自带Function使用及自定义UDF编程

2.13Hive中⾃带Function使⽤及⾃定义UDF编程UDF:User Definition Function⼀、function#查看⾃带的函数hive (db_hive)> show functions;#查看⼀个函数的详细⽤法hive (db_hive)> desc function extended split;OKtab_namesplit(str, regex) - Splits str around occurances that match regexExample:> SELECT split('oneAtwoBthreeC', '[ABC]') FROM src LIMIT 1;["one", "two", "three"]Time taken: 0.005 seconds, Fetched: 4 row(s)⼆、UDF#⾃定义UDFHive⾃带了⼀些函数,⽐如:max/min等,但是数量有限,⾃⼰可以通过⾃定义UDF来⽅便的扩展。

UDF:⽤户⾃定义函数,允许⽤户扩展HiveQL功能;##UDF(User-Defined-Function)⼀进⼀出UDAF(User-Defined Aggregation Funcation)聚集函数,多进⼀出;类似于:count/max/minUDTF(User-Defined Table-Generating Functions)⼀进多出;如lateral view explore()编程步骤:1、继承org.apache.hadoop.hive.ql.UDF2、需要实现evaluate函数;evaluate函数⽀持重载;注意事项:1、UDF必须要有返回类型,可以返回null,但是返回类型不能为void;2、UDF中常⽤Text/LongWritable等类型,不推荐使⽤java类型;创建⼀个UDF-⽅式⼀:1、Creating Custom UDFs### LowerUDF.java###package com.beifeng.senior.hive.udf;import org.apache.hadoop.hive.ql.exec.UDF;import org.apache.hadoop.io.Text;/*** 1. Implement one or more methods named* "evaluate" which will be called by Hive.** 2."evaluate" should never be a void method. However it can return "null" if* needed.* @author root**/public class LowerUDF extends UDF{public Text evaluate(Text str) {//validateif(null == str.toString()) {return null;}//lowerreturn new Text (str.toString().toLowerCase());}public static void main(String[] args) {System.out.println(new LowerUDF().evaluate(new Text("HIVE")));}}#然后打成jar包[root@hadoop-senior datas]# pwd/opt/datas[root@hadoop-senior datas]# ls hiveudf.jarhiveudf.jar2、usage#添加hive (db_hive)> add jar /opt/datas/hiveudf.jar;Added /opt/datas/hiveudf.jar to class pathAdded resource: /opt/datas/hiveudf.jar#注册,my_lower是要注册的函数名,com.beifeng.senior.hive.udf.LowerUDF是类名hive (db_hive)> create temporary function my_lower as "com.beifeng.senior.hive.udf.LowerUDF";OKTime taken: 0.012 seconds#查看hive (db_hive)> show functions;...my_lower...#测试使⽤hive (db_hive)> select ename, my_lower(ename) lowername from emp limit 5;Total jobs = 1Launching Job 1 out of 1Number of reduce tasks is set to 0 since there's no reduce operatorStarting Job = job_1554717689707_0031, Tracking URL = :8088/proxy/application_1554717689707_0031/ Kill Command = /opt/modules/hadoop-2.5.0/bin/hadoop job -kill job_1554717689707_0031Hadoop job information for Stage-1: number of mappers: 1; number of reducers: 02019-04-24 15:32:42,268 Stage-1 map = 0%, reduce = 0%2019-04-24 15:32:47,387 Stage-1 map = 100%, reduce = 0%, Cumulative CPU 1.28 secMapReduce Total cumulative CPU time: 1 seconds 280 msecEnded Job = job_1554717689707_0031MapReduce Jobs Launched:Job 0: Map: 1 Cumulative CPU: 1.28 sec HDFS Read: 894 HDFS Write: 60 SUCCESSTotal MapReduce CPU Time Spent: 1 seconds 280 msecOKename lowernameSMITH smithALLEN allenWARD wardJONES jonesMARTIN martinTime taken: 10.548 seconds, Fetched: 5 row(s)创建⼀个UDF-⽅式⼆:此⽅法jar包要位于hdfs上;CREATE FUNCTION myfunc AS 'myclass' USING JAR 'hdfs:///path/to/jar';1、##上传jar包到hdfshive (db_hive)> dfs -mkdir -p /user/root/hive/jars/;hive (db_hive)> dfs -put /opt/datas/hiveudf.jar /user/root/hive/jars/;hive (db_hive)> dfs -ls -R /user/root/hive/jars;-rw-r--r-- 1 root supergroup 910 2019-04-24 15:40 /user/root/hive/jars/hiveudf.jar#创建functionhive (db_hive)> create function self_lower as 'com.beifeng.senior.hive.udf.LowerUDF' using jar 'hdfs://:8020/user/root/hive/jars/hiveudf.jar'; converting to local hdfs://:8020/user/root/hive/jars/hiveudf.jarAdded /tmp/5356b66f-bf56-4de6-abf8-30be8029fa8b_resources/hiveudf.jar to class pathAdded resource: /tmp/5356b66f-bf56-4de6-abf8-30be8029fa8b_resources/hiveudf.jarOKTime taken: 0.025 seconds#使⽤hive (db_hive)> select ename, self_lower(ename) lowername from emp limit 5;Total jobs = 1Launching Job 1 out of 1Number of reduce tasks is set to 0 since there's no reduce operatorStarting Job = job_1554717689707_0032, Tracking URL = :8088/proxy/application_1554717689707_0032/Kill Command = /opt/modules/hadoop-2.5.0/bin/hadoop job -kill job_1554717689707_0032Hadoop job information for Stage-1: number of mappers: 1; number of reducers: 02019-04-24 15:53:28,378 Stage-1 map = 0%, reduce = 0%2019-04-24 15:53:33,504 Stage-1 map = 100%, reduce = 0%, Cumulative CPU 1.35 secMapReduce Total cumulative CPU time: 1 seconds 350 msecEnded Job = job_1554717689707_0032MapReduce Jobs Launched:Job 0: Map: 1 Cumulative CPU: 1.35 sec HDFS Read: 894 HDFS Write: 60 SUCCESSTotal MapReduce CPU Time Spent: 1 seconds 350 msecOKename lowernameSMITH smithALLEN allenWARD wardJONES jonesMARTIN martinTime taken: 10.549 seconds, Fetched: 5 row(s)。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
相关文档
最新文档