ODPS/MaxComputer 自定义UDF、UDTF函数
ODPS/MaxComputer 自定义UDF、UDTF函数
- 前置条件:
- 创建Maven工程导入jar包和打包工具:
<dependency> <groupId>com.aliyun.odps</groupId> <artifactId>odps-sdk-udf</artifactId> <version>0.29.10-public</version> </dependency>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.xxxx.comment.ODPSDate_ForMat</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
- ODPS 自定义UDF:
- 实现MySQL DATE_FORMAT()函数功能
public class ODPSDate_ForMat extends UDF { public static void main(String[] args) { System.out.println(new ODPSDate_ForMat().evaluate("2023-07", "yyyy-MM-dd hh:mm:ss", "false")); } public String evaluate(String timeStr,String outTimeType, String ifNullGetNow) { return dateformat(outTimeType,timeStr,Boolean.valueOf(ifNullGetNow)); } /** * 传入日期格式和日期,返回目标日期String * @description 日期格式转换,从一种string日期格式转换成目标string日期格式 * @param pattern 需要转换的日期格式 * @param date 需要转换的日期 如"2005-11:07.11/22:55" "2005-11:07.11/22:55" "2005-11-07" * @param ifNullGetNow 如果为空或空串,true获取当前时间的需要格式,如果为false,返回date * @return String 目标字符串日期格式 */ public static String dateformat(String pattern,Object date, boolean ifNullGetNow) { if(date == null || "".equals(date)) { if (ifNullGetNow) { return new SimpleDateFormat(pattern).format(new Date()); } else { return ""; } } String dateStr = date.toString(); //将非日期的分隔符去掉 dateStr = dateStr.replace("-", "").replace(":", "").replace(" ", "").replace("/", "").replace(".", ""); //yyyyMMddHHmmss 使用这个14位的作为标准格式 int length = 14 - dateStr.length(); // 不足14位补0 if(length > 0) { dateStr = dateStr + String.format("%0" + length + "d", 0); } Date temp; try { temp = new SimpleDateFormat("yyyyMMddHHmmss").parse(dateStr);//转换成yyyyMMddHHmmss统一格式,拿到Date格式 return new SimpleDateFormat(pattern).format(temp);//把Date格式再格式化为pattern格式的字符串日期 } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } }
- ODPS自定义UDAF函数:
- 实现需求:列转行
- 需求描述:现有一个HTML富文本字段,需要提取HTML中的所有a标签中的href中的文件路径。
- 实现方法:工具类
package com.cccc.tools; import com.cccc.bean.HtmlAlabelBean; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; public enum RegexAnalysis { /* 解析字符串中所有的<a href="upload/...">测试</a>标签中的href,text */ html_analysis("<\\s*a\\s+([\\w-\\.]+\\s*=\\s*[\"][:/\\.?'();,%&!#|=\\w-\\u4e00-\\u9fa5\\s]*[\"]\\s*)*\\s*href\\s*=\\s*[\"](.?.*upload.*)[\"]\\s*([\\w-\\.]+\\s*=\\s*[\"][:/\\.?'();,%&!#|=\\w-\\u4e00-\\u9fa5\\s]*[\"]\\s*)*\\s*>(.+?)</\\s*a\\s*>?"); private String regex_string; public static List<HtmlAlabelBean> printMatchInfo(String content, String regex) { //TODO: 存储正则取出来的数据对象 List<HtmlAlabelBean> htmlAlabelBeans=new ArrayList<>(); Pattern p = Pattern.compile(regex); Matcher m = p.matcher(content); HtmlAlabelBean htmlAlabelBean=null; while (m.find()) { //path String filePath=m.group(2); //filename String fileName=m.group(4); htmlAlabelBeans.add(new HtmlAlabelBean(fileName,filePath)); } return htmlAlabelBeans; } RegexAnalysis(String name){ regex_string = name; } public String getRegexString(){ return regex_string; } }
-
- Bean实体类:
package com.***.bean; /** * @ClassName: HtmlAlableBean * @PageName: com.***.bean * @Author: 东霖 * @CreateTime: 2023/9/13 15:39 * @Description: TODO **/ public class HtmlAlabelBean { private String fileName; private String filePath; public String getFileName() { return fileName; } public void setFileName(String fileName) { this.fileName = fileName; } public String getFilePath() { return filePath; } public void setFilePath(String filePath) { this.filePath = filePath; } public HtmlAlabelBean(String fileName, String filePath) { this.fileName = fileName; this.filePath = filePath; } }
-
- UDF实现类:
package com.ccc.comment; import com.aliyun.odps.udf.ExecutionContext; import com.aliyun.odps.udf.UDFException; import com.aliyun.odps.udf.UDTF; import com.aliyun.odps.udf.annotation.Resolve; import com.dtdream.bean.HtmlAlabelBean; import com.dtdream.tools.RegexAnalysis; import org.apache.log4j.Logger; import java.io.IOException; import java.util.List; /** * @ClassName: AnalysisHtmlContent * @PageName: com.cccc.comment * @Author: 东霖 * @CreateTime: 2023/9/12 17:46 * @Description: TODO UDTF 一进多出UDF函数 **/ // 入参类型->返回参数 @Resolve({"string->string,string"}) public class AnalysisHtmlContent extends UDTF { private static Logger logger = Logger.getLogger(AnalysisHtmlContent.class); /** * TODO:初始化方法,在UDTF处理输入数据前,调用用户自定义的初始化行为。在每个Worker内setup会被先调用一次。 * * @param ctx * @throws UDFException */ @Override public void setup(ExecutionContext ctx) throws UDFException { } /** * TODO:这个方法由框架调用,SQL中每一条记录都会对应调用一次process,process的参数为SQL语句中指定的UDTF输入参数。输入参数以Object[]的形式传入,输出结果通过forward函数输出。用户需要在process函数内自行调用forward,以决定输出数据。 * * @param args * @throws UDFException * @throws IOException */ @Override public void process(Object[] args) throws UDFException, IOException { logger.debug("start 进入数据处理......"); logger.debug("入参2为:%s"+(String)args[1]); List<HtmlAlabelBean> htmlAlabelBeans = null; // TODO: 接受传入进来的html_content String html_content = (String) args[0]; //TODO: 调用正则表达式取数据,默认取参数传入进来的正则如果不传入则传入默认值: false String regex_string = (String) args[1]; //TODO: 判断是否传入正则 if (regex_string.equals("false")) { //TODO: 如果没有传入则用自带模板正则 String regexString = RegexAnalysis.html_analysis.getRegexString(); htmlAlabelBeans = RegexAnalysis.printMatchInfo(html_content, regexString); }else{ htmlAlabelBeans = RegexAnalysis.printMatchInfo(html_content, regex_string); } for (int i = 0; i < htmlAlabelBeans.size(); i++) { HtmlAlabelBean htmlAlabelBean = htmlAlabelBeans.get(i); // 返回的数据 注意输出字段类型 forward(htmlAlabelBean.getFileName(),htmlAlabelBean.getFilePath()); } } /** * TODO:UDTF的结束方法,此方法由框架调用,并且只会被调用一次,即在处理完最后一条记录之后。 * * @throws UDFException */ @Override public void close() throws UDFException { } }
打包上传至ODPS:
本文来自博客园,作者:zhuzhu&you,转载请注明原文链接:https://www.cnblogs.com/zhuzhu-you/p/17667928.html