Hive에서 HDFS에 있는 파일을 읽어 오는데 사용하는 deserialize 메소드를 구현해보겠습니다.
Serde를 구현하는데 있어 중요한 점은 Hive의 Complex Data Type(Array, Map, Struct)을 처리하는데 있습니다. 기본적인 Primitive 타입은 해당 데이터 타입에 맞춰 deserialize 에서 읽어들인 값을 형변환만 하면 되는데 Complex 데이터 타입의 경우에는 데이터 타입이 반복이 되는 경우가 있어 재귀함수로 구현해야 합니다.
예를 들면 Array 타입의 속성에는 Hive의 어떤 데이터 타입도 넣을 수 있는데 Array<Array<Array<Array<.........>>>> 극단적으로 Array 안에 계속적으로 Array를 선언 할 수 있기 때문에 이 부분을 고려해야 합니다.
뭐든지 그렇지만 처음에는 이게 뭔소리야 싶지만 막상 코딩해보면 상당히 쉽습니다.
public Object deserialize(Writable blob) throws SerDeException { row.clear(); String[] split = blob.toString().split("\\|"); int i = 0; for (String fieldName : rowTypeInfo.getAllStructFieldNames()) { TypeInfo fieldTypeInfo = rowTypeInfo.getStructFieldTypeInfo(fieldName); row.add(parseField(split[i], fieldTypeInfo)); i++; } return row; }
private Object parseField(String field, TypeInfo fieldTypeInfo) { switch (fieldTypeInfo.getCategory()) { case PRIMITIVE: return parsePrimitive(field, fieldTypeInfo); case LIST: List<String> listFields = Arrays.asList(field.toString().split(",")); List<Object> rowList = new ArrayList<Object>(); ListTypeInfo lti = (ListTypeInfo) fieldTypeInfo; for (String listField : listFields) { Object objPrimitive = parsePrimitive(listField, lti.getListElementTypeInfo()); rowList.add(objPrimitive); } return rowList; case MAP: List<String> mapFields = Arrays.asList(field.toString().split(",")); Map<Object, Object> rowMap = new HashMap<Object, Object>(); for (String mapField : mapFields) { String[] keyValue = mapField.split(":"); MapTypeInfo mti = (MapTypeInfo) fieldTypeInfo; Object key = parsePrimitive(keyValue[0], mti.getMapKeyTypeInfo()); Object value = parseField(keyValue[1], mti.getMapValueTypeInfo()); rowMap.put(key, value); } return rowMap; case STRUCT: List<String> structFields = Arrays.asList(field.toString().split(",")); StructTypeInfo sti = (StructTypeInfo) fieldTypeInfo; ArrayList<TypeInfo> structTypes = sti.getAllStructFieldTypeInfos(); List<Object> structRow = new ArrayList<Object>(structTypes.size()); for (int i = 0; i < structTypes.size(); i++) { structRow.add(parseField(structFields.get(i), structTypes.get(i))); } return structRow; default: return null; } }
private Object parsePrimitive(String field, TypeInfo fieldTypeInfo) { PrimitiveTypeInfo pti = (PrimitiveTypeInfo) fieldTypeInfo; switch (pti.getPrimitiveCategory()) { case STRING: return field; case BYTE: return Byte.valueOf(field); case SHORT: return Short.valueOf(field); case INT: return Integer.valueOf(field); case LONG: return Long.valueOf(field); case FLOAT: return Float.valueOf(field); case DOUBLE: return Double.valueOf(field); case BOOLEAN: return Boolean.valueOf(field); case TIMESTAMP: return Timestamp.valueOf(field); case DATE: return java.sql.Date.valueOf(field); } return null; }
'Hive' 카테고리의 다른 글
Hive Serde 만들기 3 (0) | 2014.03.21 |
---|---|
Hive Serde 만들기 1 (0) | 2014.03.21 |