快捷搜索:  汽车  科技

hive识别中英文(0650-6.2.0-通过UDF实现Hive)

hive识别中英文(0650-6.2.0-通过UDF实现Hive)由上面两张图可以看出,在Hive和Impala中排序都失败了,没有按照期望中的中文对应的拼音进行排序。在Impala中:1.在Hive中创建一个表,并导入数据如下2.对s2字段进行排序select * from hanzi order by s2; 在Hive中:

作者:余枫

1.问题重现
  • 测试环境:

1.RedHat7.2

2.CDH6.2.0

3.使用root进行操作

1.在Hive中创建一个表,并导入数据如下

hive识别中英文(0650-6.2.0-通过UDF实现Hive)(1)

2.对s2字段进行排序

select * from hanzi order by s2;

在Hive中:

hive识别中英文(0650-6.2.0-通过UDF实现Hive)(2)

在Impala中:

hive识别中英文(0650-6.2.0-通过UDF实现Hive)(3)

由上面两张图可以看出,在Hive和Impala中排序都失败了,没有按照期望中的中文对应的拼音进行排序。

2.问题解决

1.想要实现对中文字段的排序,需要将中文字段转换成拼音,然后在Hive、Impala中对拼音进行排序即可。因此可以使用UDF在Java中写一个汉字转拼音的程序,然后在Hive、Impala中使用,代码如下:

public String evaluate(String ChineseLanguage) { char[] cl_chars = ChineseLanguage.trim().toCharArray(); String hanyupinyin = ""; HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat(); defaultFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE);// 输出拼音全部小写 defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);// 不带声调 defaultFormat.setVCharType(HanyuPinyinVCharType.WITH_V); try { for (int i = 0; i < cl_chars.length; i ) { if (String.valueOf(cl_chars[i]).matches("[\u4e00-\u9fa5] ")) {// 如果字符是中文 则将中文转为汉语拼音 hanyupinyin = PinyinHelper.toHanyuPinyinStringArray(cl_chars[i] defaultFormat)[0]; } else {// 如果字符不是中文 则不转换 hanyupinyin = cl_chars[i]; } } } catch (BadHanyuPinyinOutputFormatCombination e) { System.out.println("字符不能转成汉语拼音"); } return hanyupinyin; }

2.将编写好的代码打成jar包并上传到服务器

打包前在POM文件中加入配置,将所有依赖也一起打成一个jar包

<build> <plugins> <plugin> <artifactId>maven-assembly-plugin</artifactId> <configuration> <archive> <manifest> <mainClass>cn.com.gzcb.hive.udf.HanyuPinyinHelper</mainClass> </manifest> </archive> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> </configuration> </plugin> </plugins> </build> <dependency> <groupId>org.apache.hive</groupId> <artifactId>hive-exec</artifactId> <version>2.1.1-cdh6.2.0</version> </dependency> <!-- https://mvnrepository.com/artifact/com.belerweb/pinyin4j --> <dependency> <groupId>com.belerweb</groupId> <artifactId>pinyin4j</artifactId> <version>2.5.0</version> </dependency> <dependency>

hive识别中英文(0650-6.2.0-通过UDF实现Hive)(4)

使用mvn assembly:assembly命令打包,打好的包如下,以-jar-with-dependencies结尾

hive识别中英文(0650-6.2.0-通过UDF实现Hive)(5)

上传到服务器

hive识别中英文(0650-6.2.0-通过UDF实现Hive)(6)

3.将jar包上传到HDFS,创建UDF函数

上传到/user/hive/udfjar目录下

hive识别中英文(0650-6.2.0-通过UDF实现Hive)(7)

进入Hive中,创建UDF函数

create function default.parse_chinese as 'cn.com.gzcb.hive.udf.HanyuPinyinHelper' using jar 'hdfs://cdh177.macro.com:8020/user/hive/udfjar/hive-udf-0.0.1-SNAPSHOT-jar-with-dependencies.jar';

hive识别中英文(0650-6.2.0-通过UDF实现Hive)(8)

4.再次对hanzi表进行排序

select s2 parse_chinese(s2) as s3 from hanzi order by s3;

Hive

hive识别中英文(0650-6.2.0-通过UDF实现Hive)(9)

hive识别中英文(0650-6.2.0-通过UDF实现Hive)(10)

Impala

hive识别中英文(0650-6.2.0-通过UDF实现Hive)(11)

从Hive和Impala的执行结果可以看出,是按照拼音的升序成功进行了排序。

3.问题总结

无论是Hive还是Impala都不支持中文按照拼音的排序,因为它们支持的主要是标准的ASCII字符集并不包含中文,如果要对中文按照拼音排序,需要通过UDF将中文转换成拼音后实现,而中文转换成拼音的函数Java中有很多现成的参考比较方便。

猜您喜欢: