fjptec-xm 发表于 2015-7-18 11:06:41

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

  转载:http://quweiprotoss.wap.blog.163.com/   
     Solr Cell是一个针对Tika的简单适配器,它由一个SAX ContentHandler组成,ContentHandler处理SAX事件,并通过指定要抽取的域产生文档。
         在索引二制进文件的时候,有些事要注意:
  l你可以提供任何Tika支持的文档类型给Tika,Tika会尝试确定文档正确的MIME类型,然后再调用相应的解析器。如果你已经知道了正确的MIME,你可以在stream.type参数中指定。
  lSolr Cell中默认的SolrContentHandler用起来很简单。你可能发现你不止需要Solr Cell提供的功能,你还需要对数据进行一些处理来减少垃圾数据被索引。其中一种实现的方法是自定义的Solr UpdateRequestProcessor,在本章后面会讲。另一种方式是实现子类ExtractingRequestHandler的createFactory()来提供自定义的SolrContentHandler。
  l请记住如果你可能会发送很大的二进制文件,然后由Solr解析,这样速度可能会很慢。如果你只想索引元数据,那你应该用Tika来编写自己的解析器来抽取元数据,再Post给服务器,见第九章。
  你可以从Tika官网上学习到更多内容:http://tika.apache.org/。
  Configuring Solr
         在/example/cores/karaoke/conf/solrconfig.xml文件中,有对二进制文档解析的请求处理器:
  
  
  last_modified
  metadata_
  
  
         这里我们可以看到Tika的元数据属性Last-Modified被映射到了Solr的域last_modified,参数uprefix是指定没有匹配对应Solr域名的域的名字的前缀。
         Solr Cell作为contrib模块发布,它包含大约25以上的JAR文件,它们每种能解析不同的文件格式。要使用Solr Cell,我们将Solr Cell Jar和其它的JAR放到karaoke核心中,/examples/cores/karaoke/lib,它默认不被引入solr.war,也不需要其它的核心的JAR。这些JAR文件放到lib,这时只有karaoke核心可以使用它。要将这些核心在多个核心中共享,你可以将它们加入到examples/cores/lib中,并在solr.xml中指定目录:
  
         在这个例子中,我们用标准Java包javax.audio.midi将MIDI格式的karaoke文件解析。如果你知道你所解析的文件格式是什么,你可以只加入你所需要的JAR文件,这可以让你的发布包更小,但是为了完备性,我们将所有依赖的JAR全部加入,比如pdfbox,poi和icu4j在./cores/karaoke/lib。
  Solr Cell parameters
         在进入示例之前,我们看一下Solr Cell的配置参数,所有参数都是可选的。
         首先,Solr Cell决定文档的格式。它通常会猜的比较准,但它也可以与下面的参数配合:
  lResource.name:这个可选参数是指定文件的名字。它能帮助Tika来确定正确的MIME类型。
  lStream.type:这个可选参数允许你明确地指定文档MIME类型,它会优先于Tika的猜测结果。
  Tika将所有的输入文档软换为基础的XHTML文档,在头部分中包含元数据。元数据会成为域,内容的文档会映射到content域。下面的参数更详细:
  lCapture:X会被拷贝它自己的域中的HTML元素名称(比如:“p”),它可以被设置多次。
  lcaptureAttr:设置为true来获取XHTML属性到域中。一个常见的例子是用Tika抽取从抽取href属性来索引另一个域的索引。
  lxpath:允许你指定一个XPath查询,它不会将元素的文本放入content域。如果你只要得到元数据,丢弃XTHML中的正文,你可以用xpath=/xhtml:html/xhtml:head/descendant:node()。注意为每个元素使用xhtml:命名空间前缀。注意它支持一部分XPath命令。见http://tika.apache.org/0.8/api/org/apache/tika/sax/xpath/XPathParser.html。API中没有提到到它支持/descendant:node()。
  lliteral. :允许你为这个域一个特定的域值,比如,为ID域。
  现在产生的域名都应该与Schema中的域名对应。下面是控制产生域名的参数:
  llowernames:将域名都小写,并将非字母数字的字符都转换成下划线。比如Last-Updated变为last_updated。
  lfmap.:将源域名转换为目标域名。比如,fmap.last_modified=timestamp映射将由Tika产生元数据域的last_modified映射到Solr Schema中timestamp域。
  luprefix:这个前缀用于域名,如果没有加前缀的名字不匹配Schema中的域名。使用这个前缀可以与动态域中进行匹配:
  uprefix=meta_
  
  ldefaultField:如果没有指定uprefix,并没有匹配Schema中的域名,那么域的值将写入这个参数指定的域名中。这样可以将所有元数据都入一个多值的域。
  defaultField=meta
  
         其它的一些参数:
  lboost. :由参数值对指定域进行Boost,来影响打分。
  lextractOnly:设置为true,仅返回Tika解析的XHTML的文档结档,而不进行建索引。通常还会带上参数wt=json&indent=true来使XHTML更容易读。这个选项用来帮助调试。
  lextractFormat:(当extractOnly=true时)默认为xml,它产生XHMTL结构,可以设置为text产生从文档中抽取的原始文本。
  Extracting karaoke lyrics
         现在我们可以将MIDI Post给Solr /update/extract请求处理器来抽取卡拉OK的歌词。一些经典的ABBA音乐在./examples/3/karaoke/目录,是从FreeKaraoke中得到http://www.freekaraoke.com,在此感谢。
         要对Angel Eyes这首歌建索引,可以如下使用命令行:
  >> curl 'http://localhost:8983/solr/karaoke/update/extract?fmap.content=text' -F "file=@angeleyes.kar"
         不要提交你的改变:
  >> curl http://localhost:8983/solr/karaoke/update?commit=true
         你可以在发送一个文档的请求中加上commit=true请求参数进行提交,但是,在你建立大量文档时,这样做是低效的。
         我们只有一个fmap.conent=text参数来指定源中正文的文本都到text域。在这个例子中angeleyes.kar的歌词都保存到Solr的text域中。现在我们看一下索引结果:http:// localhost:8983/solr/karaoke/select/?q=*:*。你会看到下面结果:
  
  
  
  
  Angel Eyes by Abba sequenced by Michael Boyce
  tinker@worldnet.att.netSoft karaoke@KMIDI KARAOKE
  FILEWords@LENGL@TAngel Eyes@TABBA\Last night I was taking
  a walk along the river/And I saw him together with a young
girl/And the look that he gave made me shiver/'Cause
  he always used ...
  
  
  
  
         你现在已经对MIDI文件中的歌词在text域中建立索引了。但是,元数据呢?Tika解析MIDI出的数据没有利用。嗯,这是动态域一展身手的地方了。每种二进制文件格式都有着很大的不同。幸运的是,Solr Cell通过使用uprefix属性让你来将元数据映射到动态域。我们在schema.xml中使用动态域:
  
         因为有时我们想标准化地处理元数据属性,我们可以在solrconfig.xml中加入下面的配置:
  metadata_
         如果你提前知道一些元数据域的名字,并想进行域名映射,你可以配置:
  content_type
         当你搜索所有文档时,你应该可以看到Angel Eyes中所有的元数据,除了content_type外,其它都以metadata_为前缀。
  audio/midi
  0
  application/octetstream
  
  55677
  file
  16
         显然在大多情况下,你每次索引同一文件,你不想再产生一个新的Solr文档。如果在你的Schema中的uniqueKey域指定了如id的域,那你可以用literal.id=34参数提供一个特定的ID。每次你用相同的ID索引文件,它就会删除再插入这个文件。但是这就要求你要有管理ID的能力,可能需要第三方的支持,比如数据库。如果你想用元数据来做为ID,比如Tika提供的stream_name,那你可以用fmap.stream_name=id来映射域。要在这个例子中使用,更新./examples/cores/karaoke/schema.xml指定id。
  >> curl 'http://localhost:8983/solr/karaoke/update/extract?fmap.
  content=text&fmap.stream_name=id' -F "file=@angeleyes.kar"
         这要求你所定义的id是字符串型,而不是数值型。
  Indexing richer documents
         索引对MIDI文件中的卡拉OK歌词建索引是个微不足道的例子了。我们只简单的忽略了所有的内容,然后把它们存到Solr的text域中,不对文档的结构进行任何的处理。
         但是其它的文档结构,比如PDF,会更复杂,只是取得文本可能不会得到很好的搜索结果。我们看一下Take a Chance on Me,它是一个解释Monte Carlo模拟是什么的PDF文件。
         打开./examples/3/karaoke/mccm.pdf,你会看到一个复杂的PDF有很多字符,背景图片,复杂的数学公式,希腊字母,和图表。尽管这个PDF很复杂,索引它和索引卡拉OK文件一样简单:
  >> curl 'http://localhost:8983/solr/karaoke/update/extract?map.
  content=text&commit=true' -F "file=@mccm.pdf"
         如果你将文件名作为stream_name的参数进行搜索:http://localhost:8983/solr/karaoke/select/?q=stream_name:mccm.pdf,你会看到由Tika抽取出的Last_modified元数据被映射到solrconfig.xml中的last_modified域。
         其中设置的lowercase=true会将Last-Modified映射到last_modified,使它符合域名的规范。
  
  
  mccm.pdf
  
  
  Sun Mar 03 15:55:09 EST 2002
  
  
  
  Take A Chance On Me
         那么对于富文档,我们将如何处理元数据和内容呢?在URL加入extractOnly=true,它会输出Solr Cell解析出的XML文档,包括元数据域,而不对文档建索引。
         追加wt=json会使它更容易解析出内嵌的XML内容:
  >> curl 'http://localhost:8983/solr/karaoke/update/extract?extractOnly=tr
  ue&wt=json&indent=true' -F "file=@mccm.pdf"
         复制粘贴JSON输出中内嵌的XML内容,用你最喜欢的HTML浏览工具查看内容。我用的是TextMate的HTML插件,另一个不错的选择在http://xmlindent.com/。
  
  
  
  
  
  
页: [1]
查看完整版本: 企业级搜索引擎Solr 第三章 索引数据(Indexing Data)[3]