首页 > 其他分享 >ODPS/MaxComputer 自定义UDF、UDTF函数

ODPS/MaxComputer 自定义UDF、UDTF函数

时间:2023-09-13 16:11:51浏览次数:42  
标签:String 自定义 TODO UDTF UDF import com public string

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:

 

 

   

 

 

 

 

 

 

 

 

标签:String,自定义,TODO,UDTF,UDF,import,com,public,string
From: https://www.cnblogs.com/zhuzhu-you/p/17667928.html

相关文章

  • 自定义镜像-镜像结构
       ......
  • 如何实现一个数据库的 UDF?图数据库 NebulaGraph UDF 功能背后的设计与思考
    大家好,我是来自BOSS直聘的赵俊南,主要负责安全方面的图存储相关工作。作为一个从v1.x用到v3.x版本的忠实用户,在见证NebulaGraph发展的同时,也和它一起成长。BOSS直聘和NebulaGraph关于NebulaGraph在BOSS直聘的应用场景,大家可以看看之前文洲老师的文章(图数据库NebulaGr......
  • Eclipse自定义右键New菜单
    定制new菜单,点Window–>CustomizePerspective:选择new菜单所显示的快捷菜单......
  • 循序渐进介绍基于CommunityToolkit.Mvvm 和HandyControl的WPF应用端开发(3)--自定义用
    在我们创建界面元素的时候,不管在Vue3+ElementPlus的前端上,还是Winform桌面端上,都是会利用自定义用户控件来快速重用一些自定义的界面内容,对自定义用户控件的封装处理,也是我们开发WPF应用需要熟悉的一环。本篇随笔继续深入介绍介绍基于CommunityToolkit.Mvvm和HandyControl的WPF应......
  • 基于自定义表编写认证类、django-jwt源码分析、权限介绍、simpleui的使用
    基于自定义表编写认证类补充:翻译函数只要做了国际化,就会显示当前国家的语言fromdjango.utils.translationimportgettext_lazyas_msg=_('Signaturehasexpired.')#_是个函数的别名,这个函数是翻译函数,只要做了国际化,它就是中文认证类fromrest_framework_jwt......
  • 基于自定义表编写认证类、django-jwt源码分析、权限介绍
    一、基于自定义表编写认证类认证类:auth.py:#写一个类继承BaseAuthentication,重写authenticate方法fromrest_framework.authenticationimportBaseAuthenticationfromrest_framework_jwt.authenticationimportJSONWebTokenAuthenticationfromrest_framework.exception......
  • 04 自定义注解
    packageannotate;importjava.lang.annotation.*;importstaticjava.lang.annotation.ElementType.*;importstaticjava.lang.annotation.RetentionPolicy.RUNTIME;@myAnnotate(age=18)publicclassTest03{@myAnnotate1(20)//当参数只有一个时,value可以不......
  • 使用EasyExcel实现无模板、全自定义Excel导出
    1需求背景最近公司需要做一个动态字段的Excel导出,大致的样式如下:实体类如下://部门实体类publicclassDepartment{privateStringcompanyName;privateStringname;privateStringfullName;privateStringleaderName;privateStringbusiness;......
  • kubernetes部署mongoDB 单机版 自定义配置文件、密码、日志路径等
    来源:https://aijishu.com/a/1060000000097166官方镜像地址: https://hub.docker.com/_/mong...docker版的mongo移除了默认的/etc/mongo.conf,修改了db数据存储路径为/data/db.创建configmap配置,注意不能加fork=true,否则Pod会变成Completed。apiVersion:v1kind:ConfigMap......
  • jwt自定义表签发、jwt多方式登录(auth的user表)
    jwt自定义表签发继承AbstractUser,直接使用自动签发token纯自己写的用户表,需要自己签发关于签发:1、通过user生成payload,jwt提供的方法,字段必须是username,传入user,返回payload2、生成token,jwt提供的方法,把payload放入token自定义表大致流程:先创建表需要什么建什......