hive2solr multivalue功能实现

本文讲述了在使用Hive将数据推送到Solr时遇到的多值字段(multivalue)问题。默认情况下,Hive的多值字段在导入Solr后会被视为单一字符串。为了解决这个问题,文章提出了一种工作方式,即修改Hive2Solr项目的SolrWriter的write方法,将setField方法调整以正确处理多值字段。经过修改后的代码能成功导入多值字段,避免了array转换为string的错误。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

之前介绍了github上的hive2solr项目和solr的multivalue功能。
线上我们是采用hive计算完数据后推送到solr的方法,如果需要实现multivalue的话,默认的hive2solr是有些问题的。即使在hive中对于的field是多个字,导入solr之后也只是一个整体的字符串,比如下面表的数据如下:

1
2
id        test_s  test_ss
3       d       f d h

其中test_ss为multivalue类型,导入solr之后:

1
2
3
4
5
6
7
8
{
        "test_ss": [
          "f d h"  //识别为一个元素
        ],
        "test_s": "d",
        "id": "3",
        "_version_": 1472413953618346000
      }

如果直接由hive生成数组插入solr会报array转换string失败的错误。

1
2
3
4
select id,test_s,split(test_ss, ' ' ) from t2;
FAILED: NoMatchingMethodException No matching method for class org.apache.hadoop.hive.ql.udf.UDFToString
with (array<string>). Possible choices: _FUNC_(void)  _FUNC_(boolean)  _FUNC_(tinyint)  _FUNC_( smallint )
_FUNC_( int )  _FUNC_( bigint )  _FUNC_( float )  _FUNC_( double )  _FUNC_(string)  _FUNC_( timestamp )  _FUNC_( decimal )  _FUNC_( binary )

在hive向solr写入数据主要通过SolrWriter的write方法实现的,其最终是调用了SolrInputDocument的setField方法,可以通过更改代码为如下内容来workaround。
SolrWriter的write方法:

1
2
3
4
5
6
7
8
9
10
     @Override
     public void write(Writable w) throws IOException {
          MapWritable map = (MapWritable) w;
          SolrInputDocument doc = new SolrInputDocument();
          for ( final Map.Entry<Writable, Writable> entry : map.entrySet()) {
               String key = entry.getKey().toString();
               doc.setField(key, entry.getValue().toString());  //调用了SolrInputDocument的setField方法
          }
          table.save(doc);
     }

更改为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
    @Override
    public void write(Writable w) throws IOException {
            MapWritable map = (MapWritable ) w;
            SolrInputDocument doc = new SolrInputDocument();
            for ( final Map.Entry<Writable , Writable> entry : map.entrySet()) {
                    String key = entry.getKey().toString();
                    String value = entry.getValue().toString();
                    String[] sl = value.split( "\\s+" );  //即把hive输入的数据通过空格分隔,切成数组(hive的sql只要concact即可)     
                    List<String> valuesl = java.util.Arrays.asList(sl);
                    log.info( "add entry value lists:" + valuesl);
                    for (String vl :valuesl){
                            doc.addField(key,vl); //改为调用addFiled的方法,防止覆盖
                    }
            }
            table.save(doc);
    }

导入测试结果:

1
2
3
4
5
6
7
8
9
10
{
        "test_ss" : [
          "f" ,
          "d" ,
          "h"
        ],
        "test_s" : "d" ,
        "id" : "3" ,
        "_version_" : 1472422023801077800
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值