Usage with XML/HTTP Datasource
使用xml/http数据源
数据导入处理程序(DataImportHandler)可用于索引基于HTTP的数据源中的数据。这包括使用来自REST/XML API以及RSS/Atom提要(Feeds)的索引。
Configuration of URLDataSource or HttpDataSource
在solr1.4中,HttpDataSource正被弃用,取而代之的是URLDataSource 。
Sample configurations for URLDataSource <!> Solr1.4 and HttpDataSource in data config xml look like this:
此示例的数据配置如下所示:
<dataSource name="b" type="!HttpDataSource" baseUrl="http://host:port/" encoding="UTF-8" connectionTimeout="5000" readTimeout="10000"/>
<!-- or in Solr 1.4-->
<dataSource name="a" type="URLDataSource" baseUrl="http://host:port/" encoding="UTF-8" connectionTimeout="5000" readTimeout="10000"/>
特定于此数据源的额外属性是:
baseUrl :
(可选):当主机/端口在dev/qa/prod环境之间发生更改时,应该使用它。使用此属性可以隔离对solrconfig.xml所做的更改。
encoding:
编码(可选):默认情况下,使用响应头中的编码。可以使用此属性覆盖默认编码。
connectionTimeout :
(可选):默认值为5000ms
readTimeout :
(可选):默认值为10000ms
配置data-config.xml
XML/HTTP数据源的实体(entity )可以在默认属性之上具有以下属性:
processor (必需):值必须是XPathEntityProcessor。
url (必需):URL用于调用RESTAPI。(可以模板化)。如果数据源是文件,则必须是文件位置。
stream (可选):如果XML非常大,则将其设置为true。
forEach(必需):定义记录的xpath表达式。如果有多种类型的记录,用“|”(管道)将其分开。如果useSolrAddSchema 设置为“true”,则可以省略。
xsl(可选):这将用作应用XSL转换的预处理器。提供文件系统或URL中的完整路径。
useSolrAddSchema(可选):如果输入此处理器的XML与solr add xml的架构相同,则将其值设置为“true”。如果设置为true,则无需提及任何字段。
flatten (可选):如果设置为true,则无论标记名称如何,所有标记下的文本都将提取到一个字段中。SORR1.4。
实体字段可以具有以下属性(在默认属性之上):
xpath (可选):要作为记录中的列映射的字段的xpath表达式。如果列不是来自XML属性(由转换器创建的合成字段),则可以省略此项。如果在架构中将字段标记为多值,并且在给定的xpath行中找到多个值,则XPathEntityProcessor将自动处理该值。不需要额外配置
commonField:可以是(ture|false)。如果为真,则在创建SOLR文档之前,此字段一旦在记录中遇到,将被复制到其他记录中。
如果一个API支持分块(当数据集太大时),则需要多次调用才能完成该过程。XPathEntityprocessor 通过一个转换器(transformer)来支持这一点。 如果transformer返回一行,其中包含字段$hasmore的值为“true”,则处理器将使用相同的URL模板发出另一个请求(实际值在调用前重新计算)。通过返回包含字段$next url的行,转换器也可以为下一个调用传递一个全新的url,该字段的值必须是下一个调用的完整url。
XPathEntityprocessor 实现了支持xpath语法子集的流式分析器。不支持完整的xpath语法,但大多数常见的用例包括以下内容:
xpath="/a/b/subject[@qualifier='fullTitle']"
xpath="/a/b/subject/@qualifier"
xpath="/a/b/c"
xpath="//a/..."
xpath="/a//b..."
HttpDataSource的例子
在solr1.4中,httpdatasource正被弃用,取而代之的是urldatasource。
下载db部分中给出的完整导入示例以进行尝试。我们将尝试为这个示例的Slashdot RSS源建立索引。
此示例的数据配置如下所示:
<dataConfig>
<dataSource type="HttpDataSource" />
<document>
<entity name="slashdot"
pk="link"
url="http://rss.slashdot.org/Slashdot/slashdot"
processor="XPathEntityProcessor"
forEach="/RDF/channel | /RDF/item"
transformer="DateFormatTransformer">
<field column="source" xpath="/RDF/channel/title" commonField="true" />
<field column="source-link" xpath="/RDF/channel/link" commonField="true" />
<field column="subject" xpath="/RDF/channel/subject" commonField="true" />
<field column="title" xpath="/RDF/item/title" />
<field column="link" xpath="/RDF/item/link" />
<field column="description" xpath="/RDF/item/description" />
<field column="creator" xpath="/RDF/item/creator" />
<field column="item-subject" xpath="/RDF/item/subject" />
<field column="slash-department" xpath="/RDF/item/department" />
<field column="slash-section" xpath="/RDF/item/section" />
<field column="slash-comments" xpath="/RDF/item/comments" />
<field column="date" xpath="/RDF/item/date" dateTimeFormat="yyyy-MM-dd'T'hh:mm:ss" />
</entity>
</document>
</dataConfig>
此数据配置是操作所在的位置。如果您阅读Slashdot RSS的结构,它有一些标题元素,如标题(title)、链接(link)和主题(subject)。它们分别使用xpath语法映射到solr字段source、source link和subject。提要(feeds)还包含多个包含实际新闻项的项元素(item)。所以,我们要做的是,在solr中为每个“item”创建一个文档。
XPathEntityprocessor 设计为逐行传输XML(将行视为XML元素中的各个字段)。他用forEach 属性一行(row),在本例中,forEach的值为'/RDF/channel | /RDF/item'。这表示此XML有两种类型的行。(这将使用的xpath语法,并且可以有多种类型的行。)在遇到一行之后,它将尝试读取字段声明中的尽可能多的字段。因此,在这种情况下,当它读取行'/RDF/channel'时,可能会得到3个字段'source'、'source link'、'source subject'。在处理该行之后,它意识到它没有“pk”字段的任何值,因此它不会尝试为此行创建solr文档(即使它尝试了,也可能在solr中失败)。但这三个字段都标记为commonField=“true”。因此,它可以为后续的行保留值。
它向前移动并遇到/rdf/item并逐个处理行。它获取除前面的3个字段之外的所有字段的值。但是,由于它们被标记为公共字段,处理程序会在创建文档之前将这些字段放入记录中。
实体中的transformer=DateFormatTransformerr属性如何?您可以使用此功能从RESTAPI索引,例如RSS/Atom提要、XML数据提要、其他Solr服务器,甚至是格式良好的XHTML文档。我们的xpath支持有其局限性(没有通配符,只有fullpath等),但我们已经尝试确保覆盖了常见的用例,因为它基于流解析器。它非常快,即使对于大型XML,也会消耗恒定的内存量。它不支持名称空间,但可以使用名称空间处理XML。当您提供xpath时,只需删除名称空间并给出其余部分(例如,如果标记为“<dc:subject>”,则映射应只包含“subject”)。很简单,不是吗?你不需要写一行代码!享受
注意:与数据库不同,如果使用XPathEntityprocessor ,则不可能省略字段声明。它依赖于字段中声明的XPath来标识从XML中提取什么。
示例:索引维基百科
下面的data-config.xml用于索引一个完整的(en文章,仅限最新)维基百科转储。从维基百科下载的文件是pages-articles.xml.bz2,在未压缩时,磁盘上的容量大约为40GB。
<dataConfig>
<dataSource type="FileDataSource" encoding="UTF-8" />
<document>
<entity name="page"
processor="XPathEntityProcessor"
stream="true"
forEach="/mediawiki/page/"
url="/data/enwiki-20130102-pages-articles.xml"
transformer="RegexTransformer,DateFormatTransformer"
>
<field column="id" xpath="/mediawiki/page/id" />
<field column="title" xpath="/mediawiki/page/title" />
<field column="revision" xpath="/mediawiki/page/revision/id" />
<field column="user" xpath="/mediawiki/page/revision/contributor/username" />
<field column="userId" xpath="/mediawiki/page/revision/contributor/id" />
<field column="text" xpath="/mediawiki/page/revision/text" />
<field column="timestamp" xpath="/mediawiki/page/revision/timestamp" dateTimeFormat="yyyy-MM-dd'T'hh:mm:ss'Z'" />
<field column="$skipDoc" regex="^#REDIRECT .*" replaceWith="true" sourceColName="text"/>
</entity>
</document>
</dataConfig>
schema.xml的相关部分如下:
<field name="id" type="string" indexed="true" stored="true" required="true"/>
<field name="title" type="string" indexed="true" stored="false"/>
<field name="revision" type="int" indexed="true" stored="true"/>
<field name="user" type="string" indexed="true" stored="true"/>
<field name="userId" type="int" indexed="true" stored="true"/>
<field name="text" type="text_en" indexed="true" stored="false"/>
<field name="timestamp" type="date" indexed="true" stored="true"/>
<field name="titleText" type="text_en" indexed="true" stored="true"/>
...
<uniqueKey>id</uniqueKey>
<copyField source="title" dest="titleText"/>
索引8338182篇文章所用的时间约为50分钟,峰值内存使用量约为4GB。此测试是在SOLR 4.3.1版本中完成的,RamBufferSizemb设置为256MB。维基百科的转储文件在希捷7200RPM硬盘上,Solr索引文件在海盗船的强制GT固态硬盘上。
请注意,许多维基百科文章只是重定向到其他文章,使用$skipdoc<!>solr1.4允许忽略这些文章。另外,只有当regexp匹配时才定义列$skipdoc。
备注:
<dataConfig>
<propertyWriter dateFormat="yyyy-MM-dd HH:mm:ss" type="SimplePropertiesWriter" filename="my_dih.properties" locale="zh-CN" />
<dataSource name="jdbcDS" type="JdbcDataSource"
driver="oracle.jdbc.driver.OracleDriver"
url="jdbc:oracle:thin:xxxx"
user="xx"
password="U2FsdGVkX1/PqBuNUFBIcmLKTb+y41YB6J7b6tAm8Xw="
encryptKeyFile="/var/solr/data/dih-encryptionkey"
/>
<dataSource name="urlDS" type="URLDataSource"/>
<document>
<!-- <entity name="id"
query="select id,name,section,subject from CLASS_TYPE">
<field column="ID" name="id"/>
<field column="NAME" name="solr_name"/>
<field column="SECTION" name="solr_section"/>
<field column="SUBJECT" name="subject_s"/>
</entity>-->
<!-- <entity name="info" transformer="DateFormatTransformer" query="select R_CODE,R_TITLE,R_KS_ID,R_DESC,R_TYPECODE,R_FORMAT,SOLR_LAST_DATE FROM RMS_RESOURCEINFO" deltaImportQuery="select R_CODE,R_TITLE,R_KS_ID,R_DESC,R_TYPECODE,R_FORMAT,SOLR_LAST_DATE FROM RMS_RESOURCEINFO where R_CODE='${dataimporter.delta.R_CODE}'" deltaQuery="SELECT R_CODE FROM RMS_RESOURCEINFO WHERE SOLR_LAST_DATE>TO_DATE('${dataimporter.last_index_time}','yyyy-mm-dd hh24:mi:ss')">
<field column="R_CODE" name="id"/>
<field column="R_TITLE" name="rtitle_txt_cjk"/>
<field column="R_KS_ID" name="ksid_s"/>
<field column="R_DESC" name="rdesc_txt_cjk"/>
<field column="R_TYPECODE" name="rtypecode_s"/>
<field column="R_FORMAT" name="rformat_s"/>
<field column="SOLR_LAST_DATE" dateTimeFormat="yyyy-MM-dd HH:mm:ss" name="lastDate_dt"/>
</entity>-->
<entity name="slashdot"
pk="link"
url="http://192.168.119.10/interfaces/slashdot.xml"
processor="XPathEntityProcessor"
forEach="/RDF/channel | /RDF/item"
transformer="DateFormatTransformer">
<field column="source" name="source_txt_cjk" xpath="/RDF/channel/title" commonField="true" />
<field column="source-link_s" xpath="/RDF/channel/link" commonField="true" />
<field column="subject_txt_cjk" xpath="/RDF/channel/subject" commonField="true" />
<field column="title_txt_cjk" xpath="/RDF/item/title" />
<field column="link" name="id" xpath="/RDF/item/link" />
<field column="description_txt_cjk" xpath="/RDF/item/description" />
<field column="creator_s" xpath="/RDF/item/creator" />
<field column="item-subject__txt_cjk" xpath="/RDF/item/subject" />
<field column="slash-department_s" xpath="/RDF/item/department" />
<field column="slash-section_s" xpath="/RDF/item/section" />
<field column="slash-comments_s" xpath="/RDF/item/comments" />
<field column="date_dt" xpath="/RDF/item/date" dateTimeFormat="yyyy-MM-dd'T'hh:mm:ss" />
</entity>
</document>
</dataConfig>