zoukankan      html  css  js  c++  java
  • 企业级搜索引擎Solr 第三章 索引数据(Indexing Data)[2]--DIH

    转载: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。我同样禁止索引优化因为它在增量导入中不适合。

  • 相关阅读:
    Atitit.ati orm的设计and架构总结 适用于java c# php版
    Atitit.ati dwr的原理and设计 attilax 总结 java php 版本
    Atitit.ati dwr的原理and设计 attilax 总结 java php 版本
    Atitit. 软件设计 模式 变量 方法 命名最佳实践 vp820 attilax总结命名表大全
    Atitit. 软件设计 模式 变量 方法 命名最佳实践 vp820 attilax总结命名表大全
    Atitit 插件机制原理与设计微内核 c# java 的实现attilax总结
    Atitit 插件机制原理与设计微内核 c# java 的实现attilax总结
    atitit.基于  Commons CLI 的命令行原理与 开发
    atitit.基于  Commons CLI 的命令行原理与 开发
    atitit.js 与c# java交互html5化的原理与总结.doc
  • 原文地址:https://www.cnblogs.com/a198720/p/3942151.html
Copyright © 2011-2022 走看看