一、继承GenericUDTF抽象类
二、重写方法initialize()
initialize方法是针对整个任务调一次,initialize作用是定义输出字段的列名、和输出字段的数据类型,重写该方法时里面有一些知识点需要我们记
在定义输出字段(fieldNames)的数据类型(ieldOIs)时,该处定义的数据类型跟常用的Java数据类型不一致,需要格外去记。
比如string数据类型这里用的是javaStringObjectInspector;int 数据类型这里用的是javaIntObjectInspector
输出的字段名是一个集合,而不是一个字段。也就是炸裂这个方法可以输出多个列。如:hive中explode对数组炸裂时返回一个字段,explode对map数据炸裂时返回2个字段.
输出的列数据类型也是一个集合。
返回列字段名和列数据类型时,是返回的是一个工厂数据类型ObjectInspectorFactory.getStandardStructObjectInspector(fieldNames, fieldOIs),记住就好了。
三、实现抽象方法process()
process方法是一行数据调用一次process方法,即有多少行数据就会调用多少次process方法。主要作用是对传入的每一行数据写出去多次,调用forward()将数据写入到一个缓冲区。
有2个点需要记住:
1)在initialize初始化的时候,定义输出字段的数据类型是集合,我们调用forward()将数据写入到一个缓冲区,写入缓冲区的数据也要是集合。
2)如果只定义了一个集合,每次调用forward()写数据之前,需要将集合中的数据给清空。
四、实现抽象方法close()
这里没有io流的操作所以不需要关闭。
五、自定义将一行字符串转多行代码
package com.wxn;
import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
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;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class GetSimilarity extends GenericUDTF {
@Override
public StructObjectInspector initialize(StructObjectInspector argOIs) throws UDFArgumentException {
//定义输出数据的列名
List<String> structFieldNames = new ArrayList<>();
List<ObjectInspector> structFieldObjectInspectors = new ArrayList<>();
structFieldNames.add("group_idx");
structFieldObjectInspectors.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);
structFieldNames.add("cert_id");
structFieldObjectInspectors.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);
return ObjectInspectorFactory.getStandardStructObjectInspector(structFieldNames, structFieldObjectInspectors);
}
int accumulation_factor =1;
@Override
public void process(Object[] args) throws HiveException {
Integer group_idx_max= Integer.valueOf(args[0].toString());
Integer group_idx1 = Integer.valueOf(args[1].toString());
Integer group_idx2 = Integer.valueOf(args[2].toString());
//1.获取最新数据
String cert_ids1 = args[3].toString();
//2.获取上次数据
String cert_ids2 = args[4].toString();
//3.切分数据,得到一个数组
String[] words1 = cert_ids1.split(",");
String[] words2 = cert_ids2.split(",");
List<String> collect = Arrays.stream(words1).filter(Arrays.asList(words2)::contains).collect(Collectors.toList());
double result = (double) collect.size() / words2.length;
if (result >= 0.8) {
for (String word : words1) {
try {
String[] dataArray = new String[2];
dataArray[0] = group_idx1.toString();
dataArray[1] = word;
System.out.println(dataArray[0]+":"+dataArray[1]);
forward(dataArray);
} catch (Exception e) {
continue;
}
}
}else {
accumulation_factor=accumulation_factor++;
group_idx_max= group_idx_max+accumulation_factor;
for (String word : words1) {
try {
String[] dataArray = new String[2];
dataArray[0] = String.valueOf(group_idx_max);
dataArray[1] = word;
System.out.println(dataArray[0]+":"+dataArray[1]);
forward(dataArray);
} catch (Exception e) {
continue;
}
}
}
}
@Override
public void close() throws HiveException {
}
public String getDateTime(){
DateTimeFormatter dtf2 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
LocalDateTime now = LocalDateTime.now();
return dtf2.format(now);
}
public static void main(String[] args) throws HiveException {
GetSimilarity getSimilarity = new GetSimilarity();
getSimilarity.process(new Object[]{10,0,0,"a,b","a,b,c,d,e"});
}
}