2014-1-3_solr学习之(十一)solr3.5的DIH的增量索引和数据的条件导入

Solr在企业中的应用,多半是从数据库导入数据。

Solr在企业中的应用,多半是从数据库导入数据。而从数据库导入数据,最好的工具莫过于DataImportHandlerDIH的用法非常灵活,效率也很高。


关于DIH的基础配置,可以参考http://sbp810050504.blog.51cto.com/2799422/1182942


DIH中,还有一些好玩的东西,比如:


一、增量索引。


尽管DIH中讲到delta-import可以进行增量索引,但是貌似效率不高(没有去考证)。其实用full-import也可以实现增量索引。


怎么实现呢。我们把目光关注到db-data-config.xml<entity>节点上,在<entity>query属性的值一般是select * from table


当我们用http://localhost:8983/solr/dataimport?command=full-import来向索引中添加数据时,solr首先会清空索引。


如果我们用URL:


http://localhost:8983/solr/dataimport?command=full-import&clean=false


则不会清空索引。


   然后我们在 <entity>配置如下


<entity name="table_name" query="select * from table_name where updatetime > {dih.last_index_time}">


这里唯一不方便的是需要数据库表中有一个update_time的字段。


现在我们把目光关注到dih.last_index_time 。这个东西在哪里呢?我们执行full-import后,在solrconfig.xml相同的目录下会生成一个文件dataimport.properties。在这个文件中记录着dih.last_index_time 的值。



这样就可以用dih进行增量式的索引了,如果我们在linux下写个例行性工作排程,则solr可以定时更新索引。是不是很方便?


二、导入符合条件的数据


好了,如果我们想从数据库中导入特定的数据,比如id=1001,比如update_time20122013年之间的数据。该怎么做呢?



在不修改程序的前提下,solr提供了这样的功能。以导入id=1001的数据为例。


我们可以这样修改<entity>query属性:


<entity name="table_name" query="select * from table_name where id= {dih.request.id}">


对了,关键点在于dih.request.id这个属性。


那么我们怎么把id传进去呢?当然是通过url


http://localhost:8983/solr/dataimport?command=full-import&id=1001


是不是很简单?



在这些技巧其实通过看solr的源代码就能够了解到。在DocBuilder类的getVariableResolver方法中,代码如下:

public VariableResolverImpl getVariableResolver() {
    try {
      VariableResolverImpl resolver = null;
      if(dataImporter != null && dataImporter.getCore() != null
          && dataImporter.getCore().getResourceLoader().getCoreProperties() != null){
        resolver =  new VariableResolverImpl(dataImporter.getCore().getResourceLoader().getCoreProperties());
      } else resolver = new VariableResolverImpl();
      Map<String, Object> indexerNamespace = new HashMap<String, Object>();
      if (persistedProperties.getProperty(LAST_INDEX_TIME) != null) {
        indexerNamespace.put(LAST_INDEX_TIME, persistedProperties.getProperty(LAST_INDEX_TIME));
      } else  {
        // set epoch
        indexerNamespace.put(LAST_INDEX_TIME, DataImporter.DATE_TIME_FORMAT.get().format(EPOCH));
      }
      indexerNamespace.put(INDEX_START_TIME, dataImporter.getIndexStartTime());
      indexerNamespace.put("request", requestParameters.requestParams);
      indexerNamespace.put("functions", functionsNamespace);
      for (DataConfig.Entity entity : dataImporter.getConfig().document.entities) {
        String key = entity.name + "." + SolrWriter.LAST_INDEX_KEY;
        String lastIndex = persistedProperties.getProperty(key);
        if (lastIndex != null) {
          indexerNamespace.put(key, lastIndex);
        } else  {
          indexerNamespace.put(key, DataImporter.DATE_TIME_FORMAT.get().format(EPOCH));
        }
      }
      resolver.addNamespace(DataConfig.IMPORTER_NS_SHORT, indexerNamespace);
      resolver.addNamespace(DataConfig.IMPORTER_NS, indexerNamespace);
      return resolver;
    } catch (Exception e) {
      wrapAndThrow(SEVERE, e);
      // unreachable statement
      return null;
    }
  }

代码中的名为indexrnamespace的HashMap中的所有内容都可以在sql语句中通过{dih.key}的方式取得。比如dih.LAST_INDEX_TIME ,dih.request.said……等等。


wKiom1LGVVHiRPJHAAFMzbM-paQ775.jpg







你可能感兴趣的:(Solr,增量索引,solr3.5,解读,dih)