专栏首页通过使用Apache Lucene和Tika了解信息检索 - 第1部分

通过使用Apache Lucene和Tika了解信息检索 - 第1部分

介绍

在本教程中,将通过它们的核心概念(例如语法解析,MIME检测,内容分析法,索引,scoring方法,boosting方法)来解释Apache Lucene和Apache Tika框架,这些示例不仅适用于经验丰富的软件开发人员,还适用于内容分析法和编程的初学者。我们假设您具备Java™编程语言应用知识和大量可供分析的内容。

在本教程中,您将学习:

  • 如何使用Apache Tika的API及其最相关的功能
  • 如何使用Apache Lucene API及其最重要的模块开发代码
  • 如何整合Apache Lucene和Apache Tika,以构建自己的一款能有效存储和检索信息的软件。(项目代码可供下载)

什么是Lucene和Tika?

根据Apache Lucene的网站,Apache Lucene代表了一个开源的Java库,可被用于从大量文档集合中进行索引和搜索。索引大小约占索引文本大小的20-30%,搜索算法提供的功能如下:

  • 排名搜索 - 最好的结果优先返回
  • 许多强大的查询类型:短语查询,通配符查询,邻近查询,范围查询等等。在本教程中,我们将仅演示短语查询。
  • 部署搜索(例如标题,作者,内容)
  • 按任何字段排序
  • 灵活的切面,高亮显示,连接和结果分组
  • 可插入排序模型,包括Vector Space ModelOkapi BM25

但是Lucene的主要目的是直接处理文本,和我们想操作的具有各种格式和编码的文档。为了解析文档内容及其属性,Apache Tika库是必要的。

Apache Tika是一个库,它提供了一组灵活和强大的接口,可用于任何需要元数据分析和结构化文本提取的环境中。Apache Tika的关键组件是Parser(org.apache.tika.parser.Parser)接口,因为它隐藏了不同文件格式的复杂性,同时提供了一种简单而强大的机制来从各种文档中提取结构化文本内容和元数据。

Tika解析设计的标准

流式解析

该接口既不需要客户端应用程序也不需要解析器实现来将完整的文档内容保存在内存中或伪脱机发送到磁盘。这使得即使是巨大的文档也能被解析,而无需过多的资源需求。

结构化内容

解析器实现应该能够在提取的内容中包含结构信息(标题,链接等)。客户端应用程序可以使用这些信息来更好地判断解析文档的不同部分的相关性。

输入元数据

客户端应用程序应该能够将文件名或声明的内容类型等元数据与要解析的文档包含在一起。解析器实现可以使用这些信息来更好地指导解析过程。

输出元数据

除文档内容之外,解析器实现应该能够返回文档元数据。许多文档格式都包含元数据,比如作者的名字,可能对客户端应用程序有用。

上下文敏感

尽管Tika解析器的默认设置和行为在大多数使用情况下都能很好地工作,但仍然存在需要对解析过程进行更精细化控制的情况。在不破坏抽象层的情况下,将这种特定于上下文的信息注入解析过程应该很容易。

要求

  • Maven 2.0或更高版本
  • Java 1.6 SE或更高版本

第1课:从任何文件类型自动提取元数据

我们的前提条件如下:我们有一组存储在磁盘/数据库中的文档,我们希望为它们编制索引; 这些文档可以是Word文档,PDF文件,HTML文件,纯文本文件等等。由于我们是开发人员,我们希望编写可重复使用的代码来提取关于格式(元数据)的文件属性和文件内容。Apache Tika拥有一个mimetype存储库和一组方案(MIME MAGIC,URL模式,XML根字符或文件扩展名的任意组合)来确定特定文件,URL或内容是否与其中一种已知类型相匹配。如果内容确实匹配,Tika就检测它的mimetype并继续选择适当的解析器。

在示例代码中,类com.retriever.lucene.index.IndexCreator中的方法indexFile 覆盖了文件类型检测及其解析。

清单1.1用Tika分析文件

public  static DocumentWithAbstract indexFile ( Analyzer analyzer , File file ) throws IOException { 
        Metadata metadata =  new  Metadata ( ) ; 
        ContentHandler handler =  new  BodyContentHandler ( 10  *  1024  *  1024 ) ; 
        ParseContext context =  new  ParseContext ( ) ; 
        Parser parser =  new  AutoDetectParser ( ); 
        InputStream stream =  new  FileInputStream ( file ) ;  //open stream 
        try  { 
            parser . parse ( stream , handler , metadata , context ) ;  //parse the stream 
        }  catch  ( TikaException e )  { 
            e . printStackTrace ( ) ; 
        }  catch  ( SAXException e )  { 
            e. printStackTrace ( ) ; 
        }  finally  { 
            stream . close ( ) ;  //close the stream 
        } 
   //more code here 
 }

上面的代码显示了如何使用org.apache.tika.parser.AutoDetectParser解析文件;我们之所以选择这种实现方式,是因为我们希望在不考虑格式的情况下实现解析文档。另外,为了处理内容,org.apache.tika.sax.BodyContentHandler被构造为writeLimit参数(10 * 1024 * 1024); 这种类型的构造函数创建了一个内容处理程序,它将XHTML主体字符事件写入内部字符串缓冲区,以使在文档内容较大情况下抛出SAXException错误的可能性降到最低(在达到默认写入限制时抛出)。

作为解析的结果,我们获得了一个可以用来检测文件属性的元数据对象(标题或任何其他头部特定的其他文档格式)。元数据处理可以按照如下所述完成(com.retriever.lucene.index.IndexCreator,方法indexFileDescriptors):

清单1.2处理元数据

private static Document indexFileDescriptors(String fileName, Metadata metadata) {
        Document doc = new Document();
        //store file name in a separate TextField
        doc.add(new TextField(ISearchConstants.FIELD_FILE, fileName, Store.YES)); 
        
        for  ( String key : metadata . names ( ) )  { 
            String name = key . toLowerCase ( ) ; 
            String value = metadata . get ( key ) ;

            if  ( StringUtils . isBlank ( value ) )  { 
                continue ; 
            }

            if  ( "keywords" . equalsIgnoreCase ( key ) )  { 
                for  ( String keyword : value . split ( ",?(\\s+)" ) )  { 
                    doc . add ( new  TextField ( name , keyword , Store . YES ) ) ; 
                } 
            }  else  if  ( ISearchConstants . FIELD_TITLE . equalsIgnoreCase (key ) )  { 
                doc . add ( new  TextField ( name , value , Store . YES ) ) ; 
            }  else  { 
                doc . add ( new  TextField ( name , fileName , Store . NO ) ) ; 
            } 
        }

在上面介绍的方法中,我们将文件名存储在单独的字段中,同时也存储文档的标题(文档可以有与其文件名不同的标题); 我们对储存其他信息没有兴趣。

本文的版权归 mumuumum 所有,如需转载请联系作者。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 哥伦比亚大学研究人员创建隐藏嵌入文本信息新方法

    哥伦比亚工程计算机科学家发明了一种新的方法 FontCode,可以在不干扰文字的情况下将隐藏信息嵌入文本中。FontCode 创建使用字体扰动来编码信息,之后可...

    周俊辉
  • 强软弱虚引用,只有体会过了,才能记住

    Java的内存分配和内存回收,都不需要程序员负责,都是由伟大的JVM去负责,一个对象是否可以被回收,主要看是否有引用指向此对象,说的专业点,叫可达性分析。

    田维常
  • Android 安全之APK签名过程

    本篇是本系列预览的最后一篇,实则已经不属于开发者所考虑的范畴了,本系列提到的权限机制,签名细则,会在后续的文章中会一一描述。

    开发者技术前线
  • 如何评价Google最新发布的增强型风格迁移算法?

    Google最新发布了一种新的迁移网络(来自其论文《A Learned Representation for Artistic Style》)同时学习多种风格的...

    AI科技评论
  • 网络通信中基于套接字输入流和输出流的创建

      (2)由套接字对象Socket调用getInputStream()或getOutputStream()方法,分别返回具有套接字通信的基础输入流InputSt...

    Rekent
  • W5500 学习开发: 硬件使用说明

    A+,A- 作为485通信时的接收和发送数据接口,另作为422通信时的发送数据接口

    杨奉武
  • IBM和苹果的排它性协议伤了谁 合作伙伴集体拥抱Google

    苹果(Apple)与IBM日前宣布建立合作关系,向企业客户销售 iPhone 与 iPad ,并共同开发以 IBM 云端服务为后盾的特定产业应用程序;这两家公司...

    人称T客
  • JDK13快来了,JDK8的这几点应该再看看!

    jdk8虽然出现很久了,但是可能我们还是有很多人并不太熟悉,本文主要就是介绍说明一些jdk8相关的内容。

    Java技术江湖
  • 苹果押宝无人车和增强现实,开发神经引擎AI专用芯片

    【新智元导读】苹果正在开发专门处理 AI 相关任务的处理器——Apple Neural Engine。苹果已经考虑将照片应用中的面部识别、一部分语音识别以及 i...

    新智元
  • SWA2G422&485JK2G基础篇: 硬件使用说明

      A+,A- 作为485通信时的接收和发送数据接口,另作为422通信时的发送数据接口

    杨奉武

扫码关注云+社区

领取腾讯云代金券