solr dih有子查询时速度慢


这是我遇到的问题, 我有1千万条数据 ,以前的业务涉及多表我都是用联合查询,都是多对一模式,现在公司要对业务改造,产品做成京东那种多特征类似这种,每种商品的特征是不一样(可能会有多个特征),根据分片出来的数据

我的数据导入是类似以下这种形式

<dataConfig>  
  <dataSource type="JdbcDataSource"  
              driver="com.mysql.jdbc.Driver"  
              url="jdbc:mysql://localhost/dbname"  
              user="user-name"  
              password="password"/>  
  <document>  
    <entity name="outer"  
            query="select id,name,desc from mytable">  
       <field column="id" name="solr_id"/>  
       <field column="name" name="solr_name"/>  
       <entity name="inner"  
               query="select goodsAttr from another_table where id ='${outer.id}'">  
              <field column="goodsAttr" name="goodsAttr"/>  
       </entity>  
    </entity>  
  </document>  
</dataConfig> 


现在遇到的问题是 当我去查询主表mytable,然后还有个子查询another_table (another_table 是多条记录可能有几千万条数据)

我之前导数据是1千万2小时可以导完,改造成现在这种业务后 要8-10个小时,这种导数据速度 我无法忍受,于是去solr dih包源码转了转 找到解析每条Field的方法

于是找到了 org.apache.solr.handler.dataimport .DocBuilder 下有个addFieldToDoc 这个方法,该方法的主要作用是解析查询的数据转换成Document 的Field

private void addFieldToDoc(Object value, String name, float boost, boolean multiValued, DocWrapper doc) {
    if (value instanceof Collection) {
      Collection collection = (Collection) value;
      if (multiValued) {
        for (Object o : collection) {
          if (o != null)
            doc.addField(name, o, boost);
        }
      } else {
        if (doc.getField(name) == null)
          for (Object o : collection) {
            if (o != null)  {
              doc.addField(name, o, boost);
              break;
            }
          }
      }
    } else if (multiValued) {
      if (value != null)  {
        doc.addField(name, value, boost);
      }
    } else {
      if (doc.getField(name) == null && value != null)
        doc.addField(name, value, boost);
    }
  }

我的字段是数组格式存储于是我在判断是multiValued 的地方动刀子,现在是粗略为了完工判断字段写死(goodsAttr)的做的好的话应该是扩展

solr  的<field name="goods_attr" type="string" indexed="true" stored="true" multiValued="true"/> 加个strToArr="true"不过这要动大刀子,等以后有时间扩展

现在改成

  private void addFieldToDoc(Object value, String name, float boost, boolean multiValued, DocWrapper doc) {
    if (value instanceof Collection) {
      Collection collection = (Collection) value;
      if (multiValued) {
        for (Object o : collection) {
          if (o != null)
            doc.addField(name, o, boost);
        }
      } else {
        if (doc.getField(name) == null)
          for (Object o : collection) {
            if (o != null)  {
              doc.addField(name, o, boost);
              break;
            }
          }
      }
    } else if (multiValued) {
      if (value != null)  {
     if(name.equals("goodsAttr")){
     String v = (String)value;        
         String[] a = v.split(",");
         if(a != null && a.length > 0){
         for (String str : a) {
             doc.addField(name, str, boost); 
     }
         }          
     }else{
     doc.addField(name, value, boost);  
     }
      }
    } else {
      if (doc.getField(name) == null && value != null)
        doc.addField(name, value, boost);
    }
  }


也就是我之前子查询 我之前都把值存进 主表以逗号分割存进一个字段 叫 goodsAttr(例如:佩戴方式_头戴式,类型_耳麦),然后导数据对逗号分割的字符串处理


现在导数据速度又恢复到以前的2个多小时


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值