转载:http://quweiprotoss.wap.blog.163.com/w2/

DIH需要在solrconfig.xml中注册,如下:

<requestHandler name="/dih_artists_jdbc"

class="org.apache.solr.handler.dataimport.DataImportHandler">

<lst name="defaults">

<str name="config">mb-dih-artists-jdbc.xml</str>

</lst>

</requestHandler>

被引用的md-dih-artist-jdbc.xml位于<solr-home>/conf,它指定了数据导入过程的细节。我们会稍涉及一下这个文件。

The development console

在描述DIH配置文件之前,我们将看一下DIH开发控制台。访问下面的URL:

http://localhost:8983/solr/mbartists/admin/dataimport.jsp

如果注册了多个请求handler,你会看到页面上列出了它们的链接,链接指向这个Handler的开发的控制台。开发控制台如下图所示:

页面分为两部分:在左边的DIH控制界面,右边是命令以XML输出的结果。

控制界面还分为了开发区和调试区,包含了一个对配置文件的临时编辑,页面底部是重要的DIH命令列表。

本章后面会介绍提交一个命令到DIH的细节。

Writing a DIH configuration file

DIH配置文件的关键部分包括一个数据源(data source),一个实体(entity),一些转换器(transformers)和一些域列表。配置中有很多这些的东西,但有时它们可以被忽略。首先我会列表一些DIH组件,并写一些对组件简单的描述。然后我会给你一个示例配置,来展示这些组件是如何配置起来工作的。

Data Sources

如你所想,<dataSource/>是由一个实体引用的数据源。这是配置中最简单的一段。Type属性指定了类型,默认为JdbcDataSource。根据类型的不同,可以指定其它的属性(这里没有列出)。也可以有多个数据源,但这种做法不常见。并且除了JdbcDataSource之外,每种类型都会处理二进制或是文本数据,下面是可用的数据源类型。它们的名字都以DataSource结尾。

l  JdbcDataSource:通过JDBC访问数据库,通常是关系数据库。

l  FieldStreamDataSource,FieldReaderDataSource:从JdbcDataSource的列中抽取二进制或是字符数据。

l  BinFileDataSource,FileDataSource:指定一个二进制或是文本文件的路径。

l  URLDataSource:指定一个文本数据源的URL。

l  BinContentStreamDataStream,ContentStreamDataSource:接收Post到DIH的二进制或是文本数据,而不是由DIH从其它地方拉数据。

如果你在找MailDataSource,其实是没有的。MailEntityProcessor里包含了从数据源抓取邮件的功能。

Entity processors

在<document/>元素之后,有一个或多个<entity/>元素,这些元素会被实体处理器(Entity Processor)中的processor属性引用。默认的是SqlEntityProcessor。一个实体处理器执行时会产生文档集合。产生文档的数据通常是从所指定的数据源中取得。在<document>元素的第一个儿子默认是根实体(root entity),它表示它的文档会被Solr索引。如果rootEntity属性被显式地设置为false,那么DIH会反向查找,直到找到一个实体配置没有设置为false的。可以有子实体(sub-entities),它通常为每个父文档执行一次,并通常由父文档引用来缩小查找范围。子实体的文档会合并到根实体的文档中,如果多个子实体对相同的域产生了多个文档,那么根实体会产生一个多值域。

实体处理器(s)有一些属性配置是通用的,有一些是特有的。

实体处理器名字都以EntityProcessor结尾。下面是处理器列表:

l  SqlEntityProcessor:引用一个JdbcDataSource并执行一个特定的SQL查询。结果集中的列将映射到相同域名的域中。这个处理器是唯一支持增量导入的。

l  CachedSqlEntityProcessor:与SqlEntityProcessor相似,但它不是每次都执行Sql查询,而是将每条记录Cache到内存以便以后查找。它是根实体的子实体唯一的选择。

l  XPathEntityProcessor:从文本数据源中处理XML。它根据XPath表达式将XML分成文档。通过XPath表达式来引用XML中的一部分内容作为域。

l  PlainTextEntityProcessor:从文本数据源中读取数据,然后将数据作为一个域值。

l  LineEntityProcessor:将文档数据源的每一行产生一个文件。

l  FileListEntityProcessor:查找所有满足条件的文件,为找到每个文件产生一个文档,文档中包含文件的路径。一个如Tika子实体就可以从文件中抽取文本。

l  TikaEntityProcessor:用Tika从二进制数据源中抽取文本。Tika支持多种文件类型,如HTML,PDF和Microsoft Office文档。

l  MailEntityProcessor:从IMAP邮件服务器取得e-mail,包括用Tika处理附件。它不用数据源。你可以指定一个起始时间,但不幸的是,它不支持DIH增量更新。

Fields and transformers

在一个<entity>中有一些<field/>元素,它们定义了Sql查询中的列如果映射到Solr。Field元素必须有一个column属性,它对应于SQL查询中的字段名。Name属性是Solr Schema中的域名,即字段名要映射的域名。如果它没有指定,那么它就默认为字段名。当结果集中的列不需要再做进一步处理,其实没有必要去写域的定义,因为定义已经被隐式定义了。

实体定义中我们还没有提及的是transformer,它定义了一个创建,修改,删除域的transformer列表,列表以逗号分隔。

很关键的一点是,Transformer是按顺序进行的。通常Transformer作用于指定使用的域上,它会对域值进行一些处理,可能是将域值切分成多个值,或是对域值进行格式化,或是其它。下面是Transformer的一个列表:

?    TemplateTransformer:基于一个字符串模板的对域值进行重写或是修改。模板中可以包含对其它域的引用并能使用DIH变量。

?    RegexTransformer:可以进行字符串替换,将域值切分成多值,或是将域值映射到不同的域中。这个Transformer非常有用!

?    DateFormatTransformer:根据指定的模式解析日期-时间格式。输出格式是Solr的日期格式。

?    NumberFormatTransformer:根据本地设置和风格(即数字,百分比,整形,货币格式)解析一个数字。输出是一个适用于Solr的某一数值域类型的普通数值。

?    HTMLStripTransformer:将HTML标签根据HTMLStripCharFilter(在前面章节有描述)移除。在这一步进行移除,而不是在文本分析组件中移除,可以让Stored的内容是清洁的,而不仅仅是索引的数据。

?    ClobTransformer:将数据库中的CLOB中的值转换成一个普通字符串。

?    LogTransformer:使用字符串模板如TemplateTransformer,可以为分析Transformer处理过程记录日志。不同于多数Transformer,它在实体中配置,因为它是进行分析每个实体输出的结果,而不是每个域。

?    ScriptTransformer:调用用户定义在<script/>元素中的代码。这个Transformer很特殊地在transformer属性中配置,用…,script:myFunctionName, …配置,其中myFunctionName是所提供代码中的函数名。代码默认是JavaScript,但是其它可以在JVM上运行的语言大多也都是支持的。

Example DIH configurations

DIH会因为数据是否是数据库,内容是否是XML,或是文本是否要从文档中抽取出来,而使用配置看起来非常不同。

Importing from databases

下面是mb-dih-aritsts-jdbc.xml配置文件,其中有一个比较长的SQL查询:

<dataConfig>

<dataSource name="jdbc" driver="org.postgresql.Driver"

url="jdbc:postgresql://localhost/musicbrainz_db"

user="musicbrainz" readOnly="true" autoCommit="false" />

<document>

<entity name="artist" dataSource="jdbc" pk="id" query="

select

a.id as id,

a.name as a_name, a.sortname as a_name_sort,

a.begindate as a_begin_date, a.enddate as a_end_date,

a.type as a_type,

array_to_string(

array(select aa.name from artistalias aa

where aa.ref = a.id ),

'|') as a_alias,

array_to_string(

array(select am.name from v_artist_members am

where am.band = a.id order by am.id),

'|') as a_member_name,

array_to_string(

array(select am.id from v_artist_members am

where am.band = a.id order by am.id),

'|') as a_member_id,

(select re.releasedate from release re inner join

album r on re.album = r.id where r.artist = a.id

order by releasedate desc limit 1)

as a_release_date_latest

from artist a

"

transformer="RegexTransformer,DateFormatTransformer,

TemplateTransformer">

<field column = "id" template="Artist:${artist.id}" />

<field column = "type" template="Artist" />

<field column = "a_begin_date"

dateTimeFormat="yyyy-MM-dd" />

<field column = "a_end_date"

dateTimeFormat="yyyy-MM-dd" />

<field column = "a_alias" splitBy="\|" />

<field column = "a_member_name" splitBy="\|"/>

<field column = "a_member_id" splitBy="\|" />

</entity>

</document>

</dataConfig>

如果dataSource中的type属性没有指定,它默认为JdbcDataSource。熟悉JDBC的读者应该发现这个例子中的属性很熟悉,另外还有其它的属性可以设置。你可以在wiki中找到全部的属性。

<entity/>中最重要的部分是在query属性中配置的,它是一个SQL查询。这个查询里有一些子查询。子查询的结果为数组,数组用空格连接转换为字符串。不同的数据库会用不同的语法来实现这些功能。

Importing XML from a file with XSLT

在本例中,我们将从磁盘中导入一个XML文件,并用XSLT完成大部分工作,而不使用DIH Transformer。

<dataConfig>

<dataSource name="artists" type="FileDataSource" encoding="UTF-8"/>

<document name="artists">

<entity name="artist" dataSource="artists"

url="downloads/artists_veryshort.xml"

processor="XPathEntityProcessor"

xsl="cores/mbtype/conf/xslt/artists.xsl"

useSolrAddSchema="true">

</entity>

</document>

</dataConfig>

FileDataSource类型的dataSource是对文本文件配置。实体的URL是相对数据源中baseUrl的路径。在配置中它没有设置,所以它默认是服务器的当前工作目录。XSLT文件是相对当前工作目录,而不是conf目录——它是一个已知的bug:SOLR-1226。要查看被引用的XSLT文件,请下载本书的补充资料。

这个例子有意思的地方是它不仅使用XSLT并且还使用了useSolrAddSchema属性,它会使结果XML结构为<add><doc><field name=…结构。我们的输入是HTML,XSLT文件转换了它。这两个选项最好结合使用。

Importing multiple rich document files (crawling)

在这个例子中,我们的配置会爬取所有一个目录中的PDF文件,然后抽取其中的文本和元数据。

<dataConfig>

<dataSource type="BinFileDataSource" />

<document>

<entity name="f" dataSource="null" rootEntity="false"

processor="FileListEntityProcessor"

baseDir="/my/file/path" fileName=".*pdf"

recursive="true">

<entity name="tika-test" processor="TikaEntityProcessor"

url="${f.fileAbsolutePath}" format="text">

<field column="Author" name="author" meta="true"/>

<field column="title" name="title" meta="true"/>

<field column="text" name="text"/>

</entity>

</entity>

</document>

</dataConfig>

FileListEntityProcessor是进行文件爬取的部分,它并不需要一个数据源,但配置中必须指定。因为指定了rootEntity=”false”,所以它不是一个根实体,在里面的子实体才是一个根,实体,它对应Solr文档。实体名为f,子实体名为tika-test,子实体在它的url中用变量f.fileAbsolutePath引用了f中指定的路径。这个例子使用了变量替换语法${…}。

提到这,其实DIH中有大量的变量用于替换,包括在solr.xml和solrconfig.xml中的定义的变量。同样,你可以看DIH wiki查看更多细节。

TikaEntityProcessor部分很直观。Tika产生大量的元数据,本例中只使用两个。

Importing commands

导入全部数据称为全量导入(full import),相对的是增量导入(delta import)。命令是在DIH请求处理器的commmand属性中指定。我们可以用下面的URL告诉DIH进行一次全量的导入:

http://localhost:8983/solr/mbartists/dataimport?command=full-import。

在命令行中我们可以用:

curl http://localhost:8983/mbartists/solr/dataimport -F command=full-import

它使用HTTP POST,它比前面介绍的GET更合理一些。

不同于其它的导入机制,DIH立即返回HTTP响应,并继续异步处理。要得到DIH当前的状态。访问URL:http://localhost:8983/solr/mbartists/dataimport,你会得到如下的输出:

<response>

<lst name="responseHeader">

<int name="status">0</int>

<int name="QTime">15</int>

</lst>

<lst name="initArgs">

<lst name="defaults">

<str name="config">mb-dih-artists-jdbc.xml</str>

</lst>

</lst>

<str name="status">idle</str>

<str name="importResponse"/>

<lst name="statusMessages"/>

<str name="WARNING">This response format is experimental. It islikely to change in the future.</str>

</response>

命令的属性默认设置为status,它的返回就是上面的输出。当导入正在进行时,它会显示一些进度的统计信息,和状态为busy。

其它布尔参数clean,commit和optimize可能也会带在命令中,并且其它默认设置为true。Clean是DIH中的参数,它是指在导入文档之前,先将所有文档删除。要自定义文档如何被删除,你可以在根实体的preImportDeleteQuery属性指定。你甚至可以在postImportDeleteQuery属性中指定在一次导入后删除文档。查询的语法在第四章介绍。

另两个有用的命令是reload-config和abort。第一个是导入DIH配置文件,它可以在不重启Solr的情况下改变配置。第二个命令是取消任何正在进行的导入。

Delta imports

DIH支持它称为增量导入(delta import)的功能,它只获取自上次获取后改变的数据。只有SqlEntityProcessor支持增量导入,并且它假设你的数据是打时间戳的。 官方wiki中有详细的介绍。它在实体中使用deltaImportQuery和deltaQuery属性对,和一个delta-import命令。这个方法很麻烦,很难维护,并且它比起新的方法速度慢,文档在:http://wiki.apache.org/solr/DataImportHandlerDeltaQueryViaFullImport。

你要在SQL的WHERE子句中引入时间戳以进行增量更新。并要检查clean参数,clean是指示一个增量更新或是全量更新是否应该进行。下面是一个简洁的<entity/>定义:

<entity name="item" pk="ID"

query="SELECT * FROM item

WHERE '${dataimporter.request.clean}' != 'false'

OR last_modified > '${dataimporter.last_index_time}'">

注意${…}参数替换语法,要进行全量导入,要使用clean=true的全量导入命令:/dataimport?command=full-fullimport&clean=true。对于一个增量导入,我们仍用full-import命令,但我们设置clean为false:/dataimport?command=full-import&clean=false&optimize=false。我同样禁止索引优化因为它在增量导入中不适合。

企业级搜索引擎Solr 第三章 索引数据(Indexing Data)[2]--DIH的更多相关文章

  1. 企业级搜索引擎Solr 第三章 索引数据(Indexing Data)[1]

    转载:http://quweiprotoss.wap.blog.163.com/ Push data to Solr or have Solr pull it 尽管一个应用通过HTTP方式与Solr通 ...

  2. 企业级搜索引擎Solr 第三章 索引数据(Indexing Data)[1] (转)

    Index Data Author: David Smiley Eric Pugh 译者:Koala++ / 屈伟 在这一章中我们将了解如何将数据传入Solr.这个传入的过程称之为索引,尽管中间还包含 ...

  3. 企业级搜索引擎Solr 第三章 索引数据(Indexing Data)[3]

    转载:http://quweiprotoss.wap.blog.163.com/ Solr Cell是一个针对Tika的简单适配器,它由一个SAX ContentHandler组成,ContentHa ...

  4. 企业级搜索引擎Solr 第三章 索引数据(Indexing Data)

    虽然本书中假设你要建索引的内容都是有着良好结构的,比如数据库表,XML文件,CSV,但在现实中我们要保存很混乱的数据,或是二进制文件,如PDF,Microsoft Office,甚至是图片和音乐文件. ...

  5. MVC5+EF6 简易版CMS(非接口) 第三章:数据存储和业务处理

    目录 简易版CMS后台管理系统开发流程 MVC5+EF6 简易版CMS(非接口) 第一章:新建项目 MVC5+EF6 简易版CMS(非接口) 第二章:建数据模型 MVC5+EF6 简易版CMS(非接口 ...

  6. .Net程序员 Solr-5.3之旅 (三)Solr 从MSSQ导入索引数据

    阅读目录 引言 准备工作 data-config.xml schema.xml 导入数据 结尾 附件下载 引言 Other men live to eat, while I eat to live.- ...

  7. 企业级搜索引擎Solr使用入门指南

    由于搜索引擎功能在门户社区中对提高用户体验有着重在门户社区中涉及大量需要搜索引擎的功能需求,目前在实现搜索引擎的方案上有集中方案可供选择: 基于Lucene自己进行封装实现站内搜索. 工作量及扩展性都 ...

  8. 【solr】SolrCloud中索引数据存储于HDFS

    SolrCloud中索引数据存储于HDFS 本人最近使用SolrCloud存储索引日志条件,便于快速索引,因为我的索引条件较多,每天日志记录较大,索引想到将日志存入到HDFS中,下面就说说怎么讲sol ...

  9. C#高级编程第11版 - 第三章 索引

    [1]3.1 创建及使用类 1.构造函数:构造函数的名字与类名相同: 使用 new 表达式创建类的对象或者结构(例如int)时,会调用其构造函数.并且通常初始化新对象的数据成员. 除非类是静态的,否则 ...

随机推荐

  1. ntpd和ntpdate

    以无GUI 的Ubuntu 为例 1. ntpdate ntpdate是Ubuntu发行版的标配.按Ubuntu14.04的官方文档(这里),Ubuntu在启动时,会调用ntpdate,根据Ubunt ...

  2. C#操作Access的一些小结

    C#操作Access的一些小结 好久没有写blog,感觉今年一年都没怎么真正开心过,整天有一些事围绕在身边,使心情难以平静下来,真正写点有意义的东西.博客园是天天看的,看得多,写的少,偶尔也是Copy ...

  3. LightOJ 1112 Curious Robin Hood (单点更新+区间求和)

    http://lightoj.com/volume_showproblem.php?problem=1112 题目大意: 1 i        将第i个数值输出,并将第i个值清0 2 i v     ...

  4. Lotus 迁移到Exchange 2010 POC 之在Exchange 2007安装Transport Suite!

    我们登录到Exchange 2007服务器,下载Transport 组件,下载地址如下,我们由于安装在Exchange 服务器上,所以需要安装64位版本:

  5. Add mappings to an Elasticsearch index in realtime

    Changing mapping on existing index is not an easy task. You may find the reason and possible solutio ...

  6. js 如何验证字符串里是否包含汉字?

    1.用正则表达式判断<input  type="text" id="name" placeholder="请输入用户名" value= ...

  7. 动态链接库 仅有.dll文件时候的使用方法

    在没有.h和.lib文件时,需要函数指针和WIN32 API函数 LoadLibrary, GetProcAddress 和FreeLibrary 只需要.dll文件即可(将.dll文件置入工程目录中 ...

  8. com.sun.image.codec.jpeg--导入报错

    import com.sun.image.codec.jpeg; 这样导入的时候,总是报错:Only a type can be imported. com.sun.image.codec.jpeg ...

  9. DAG成员服务器还原

    DAG成员服务器 exmb02 已损坏: 1.使用 Get-MailboxDatabase cmdlet 为要恢复的服务器上的任何邮箱数据库副本检索所有重播延迟和截断延迟设置:   Get-Mailb ...

  10. clientTop scrollTop offsetTop

    关于top.clientTop.scrollTop.offsetTop的用法 网页可见区域宽: document.body.clientWidth;网页可见区域高: document.body.cli ...