hadoop - functions - hive timestamp data type
Colgar texto UDF en matriz (2)
Intento crear un UDF para Hive que me da más funcionalidad que la función split()
ya provista.
import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.io.Text;
public class LowerCase extends UDF {
public Text evaluate(final Text text) {
return new Text(stemWord(text.toString()));
}
/**
* Stems words to normal form.
*
* @param word
* @return Stemmed word.
*/
private String stemWord(String word) {
word = word.toLowerCase();
// Remove special characters
// Porter stemmer
// ...
return word;
}
}
Esto está funcionando en Hive. Exporto esta clase a un archivo jar. Luego lo cargo en Hive con
add jar /path/to/myJar.jar;
y crea una función usando
create temporary function lower_case as ''LowerCase'';
Tengo una tabla con un campo String. La declaración es entonces:
select lower_case(text) from documents;
Pero ahora quiero crear una función que devuelva una matriz (como, por ejemplo, dividir).
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.io.Text;
public class WordSplit extends UDF {
public Text[] evaluate(final Text text) {
List<Text> splitList = new ArrayList<>();
StringTokenizer tokenizer = new StringTokenizer(text.toString());
while (tokenizer.hasMoreElements()) {
Text word = new Text(stemWord((String) tokenizer.nextElement()));
splitList.add(word);
}
return splitList.toArray(new Text[splitList.size()]);
}
/**
* Stems words to normal form.
*
* @param word
* @return Stemmed word.
*/
private String stemWord(String word) {
word = word.toLowerCase();
// Remove special characters
// Porter stemmer
// ...
return word;
}
}
Lamentablemente, esta función no funciona si hago exactamente el mismo procedimiento de carga mencionado anteriormente. Me aparece el siguiente error:
FAILED: SemanticException java.lang.IllegalArgumentException: Error: name expected at the position 7 of ''struct<>'' but ''>'' is found.
Como no he encontrado ninguna documentación que mencione este tipo de transformación, ¡espero que me des un consejo!
No creo que la interfaz ''UDF'' proporcione lo que quieres. Desea usar GenericUDF. Usaría la fuente de la UDF dividida como guía.
En realidad, la interfaz ''UDF'' admite la devolución de una matriz.
Devuelve ArrayList<Text>
o incluso ArrayList<String>
lugar de Text[]
Tu código debería verse así:
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.io.Text;
public class WordSplit extends UDF {
public ArrayList<String> evaluate(final Text text) {
ArrayList<String> splitList = new ArrayList<String>();
StringTokenizer tokenizer = new StringTokenizer(text.toString());
while (tokenizer.hasMoreElements()) {
String word = stemWord((String) tokenizer.nextElement());
splitList.add(word);
}
return splitList;
}
/**
* Stems words to normal form.
*
* @param word
* @return Stemmed word.
*/
private String stemWord(String word) {
word = word.toLowerCase();
return word;
}
}