cvbf333 发表于 2013-12-23 09:48:22

Solr4:数据导入(dataimport)时,不符合Solr日期类型要求的...

Solr4:数据导入(dataimport)时,不符合Solr日期类型要求的字段的处理
背景:
要求将一个SQL Server2012版本中的数据库导入到Solr中。数据表中有一字段用来存储birthday日期字段,为nvarchar类型,长度为8,格式为:yyyyMMdd。

导入Solr数据结构字段名为birthday,字段类型为date。

Solr的date是不认yyyyMMdd格式的日期的,它要求格林威治时间格式,这就要求转换。示范:“19800103”转换为“1980-01-03T00:00:00.000Z”。

思路一:
在SQL查询数据时做转换,用到cast函数与dateadd函数。因为时区问题。语句如下:

select top 100 dateadd(hour,8,cast(Birthday as datetime)) Birthday from dbo.INFO
这样并没有彻底解决问题,因为数据的不正确性,有数据压根就不是yyyyMMdd格式的。

思路二:
在Solr中想办法,就是在数据进来时,判断日期的正确性,不正确赋初始值;正确转换为Solr接受的日期格式。

Solr的schema.xml中,date字段对应的类为TrieDateField,完整包名为:org.apache.solr.schema.TrieDateField。查看TrieDateField代码,最终生成日期的为org.apache.solr.schema.DateField类的parseMath(Date now, String val)方法。

对DateField.java文件作少许改动,以适应8位长度的日期。代码如下:


    public Date parseMath(Date now, String val) {
      String math = null;
      final DateMathParser p = new DateMathParser();

      if (null != now)
            p.setNow(now);

      if (val.startsWith(NOW)) {
            math = val.substring(NOW.length());
      } else {
            final int zz = val.indexOf(Z);
            if (0 < zz) {
                math = val.substring(zz + 1);
                try {
                  // p.setNow(toObject(val.substring(0,zz)));
                  p.setNow(parseDate(val.substring(0, zz + 1)));
                } catch (ParseException e) {
                  throw new SolrException(SolrException.ErrorCode.BAD_REQUEST,
                            "Invalid Date in Date Math String:'" + val + '\'', e);
                }
            } else {
                if (val.trim().equals("")) {
                  // 注意:数据为空字符串,或者由空格组成,返回1970...,只是因为自己项目的需要
                  return new Date(0L);
                }

                if (val.length() == 8) {
                  try {
                        Calendar cal = Calendar.getInstance();
                        cal.set(Integer.parseInt(val.substring(0, 4).trim()),
                              Integer.parseInt(val.substring(4, 6).trim()) - 1,
                              Integer.parseInt(val.substring(6, 8).trim()));
                        p.setNow(cal.getTime());
                  } catch (NumberFormatException e) {
                        e.printStackTrace();

                        // 注意:解析不成功返回1970...,只是因为自己项目的需要;
                        return new Date(0L);
                  }
                } else {
                  throw new SolrException(SolrException.ErrorCode.BAD_REQUEST,
                            "Invalid Date String:'" + val + '\'');
                }
            }
      }

      if (null == math || math.equals("")) {
            return p.getNow();
      }

      try {
            return p.parseMath(math);
      } catch (ParseException e) {
            throw new SolrException(SolrException.ErrorCode.BAD_REQUEST,
                  "Invalid Date Math String:'" + val + '\'', e);
      }
    }

将此类生成的class文件放到solr\WEB-INF\lib\solr-core-4.6.0.jar包中,重新启动tomcat,经测试,问题解决。

51qsx 发表于 2013-12-23 11:15:56

双方都属神经质的星座.彼此疑神疑鬼,最后可说是身心俱疲,两败俱伤,只有由爱生恨而已.

Mrfei 发表于 2013-12-23 18:55:55

真是收益匪浅

浪人 发表于 2013-12-23 23:25:49

世界那么大,为什么还要执着于某一个人念念不忘呢

fateame 发表于 2013-12-24 03:01:44

眼泪是记得。而不哭是懂得、我们都会幸福的

撒的阿坎努斯 发表于 2013-12-24 06:20:00

楼主辛苦了

wstlwl 发表于 2013-12-24 08:25:52

只想抱着你的背脊不想放为何美的东西总叫人感伤
页: [1]
查看完整版本: Solr4:数据导入(dataimport)时,不符合Solr日期类型要求的...