package DF;
import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.hive.ql.exec.UDF;
import org.json.JSONException;
import org.json.JSONObject;
public class BaseFiledJson extends UDF {
//重写evaluate方法 返回一个string 穿进去第一个值是整个json数据 line和公共字段的所有key
public String evaluate(String line,String jsonkeysString){
StringBuilder sb = new StringBuilder();
//获取所有key
String[] jsonkeys = jsonkeysString.split(",");
//line 15015616|{}
String[] logcontents = line.split("\\|");
//校验进来的字符串是否是正确的,blank可以一次性校验null,""," ",
if(logcontents.length!=2|| StringUtils.isBlank(logcontents[1])){
return "";
}
try {
//此时logcontents是一个完整的json字符串{}
JSONObject jsonObject = new JSONObject(logcontents[1]);//timestamp|{"cm":{"k":"v","k":"v"}}
//获取公共字段的json
JSONObject cmjson = jsonObject.getJSONObject("cm");
//循环遍历
for(int i=0;i<jsonkeys.length;i++){
String jsonkey = jsonkeys[i].trim();//获取每一个key
if(cmjson.has(jsonkey)){
sb.append(cmjson.get(jsonkey)).append("\t");//每个字段按照\t拼接
}else {
sb.append("\t");//如果没有获取到则直接\t拼接
}
}
//拼接事件字段和服务器时间
sb.append(jsonObject.getString("et")).append("\t");//得到的就是[{"ett":sdasd,"en":"asdasd"}]此时就不存在et了 只存在这个数组
sb.append(logcontents[0]).append("\t");
} catch (JSONException e) {
e.printStackTrace();
}
return sb.toString();
}
//拿到的是公共字段和事件字段的json
}
==================================================================================================
package DF;
import org.apache.commons.lang.StringUtils;
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.PrimitiveObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.StructObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory;
import org.json.JSONArray;
import org.json.JSONException;
import java.util.ArrayList;
import java.util.List;
public class EventJson extends GenericUDTF {
@Deprecated
public StructObjectInspector initialize(ObjectInspector[] argOIs) throws UDFArgumentException {
//定义返回值的名称和返回值的类型
List<String> fieldname=new ArrayList<>();
List<ObjectInspector> fieldType=new ArrayList<>();
fieldname.add("event_name");
fieldType.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);
fieldname.add("event_json");
fieldType.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);
return ObjectInspectorFactory.getStandardStructObjectInspector(fieldname,fieldType);
}
@Override//一进多出 这个object[]数组传进来的不是et了而是一个整条数组[{"ett":sdasd,"en":"asdasd"}]
public void process(Object[] objects) throws HiveException {
//具体的业务 获取输入的数据
String input = objects[0].toString();//因为所有的json都在一条数组里面 所以只需要拿到0下标就可以算是拿到这个数组了
if(StringUtils.isBlank(input)){
return ;
}else {
try {
JSONArray jsonArray = new JSONArray(input);//此时拿到了json数组了,然后一个个解析拿取事件和数组内的第一条json,第二条json,第三条json等等,这些json在后续用hive函数get_jsonobject解析也可以
//循环遍历json的值,一个一个的封装到string数组里 拿到事件名称和json值
for(int i=0; i<jsonArray.length();i++){
String[] result= new String[2];//存放俩个值,一个是名称一个是json数据
result[0]= jsonArray.getJSONObject(i).getString("en");//事件名称
result[1]=jsonArray.getString(i);//事件整体 [{"ett":"assd"}]
forward(result);//相当于context发送
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
@Override
public void close() throws HiveException {
}
//获取事件的字段
}
1029





