您的位置:首页 > 大数据 > 人工智能

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

2014-01-03 14:14 429 查看
Solr在企业中的应用,多半是从数据库导入数据。
Solr在企业中的应用,多半是从数据库导入数据。而从数据库导入数据,最好的工具莫过于DataImportHandler,DIH的用法非常灵活,效率也很高。

关于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_time在2012到2013年之间的数据。该怎么做呢?

在不修改程序的前提下,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……等等。


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息