文档搜索-TIKA 读取文档内容

2,650次阅读
没有评论

背景

进行文档搜索的基本前提是拿到文档内容,抽取文档内容的工具比较多,用过的有aspose,POI,NPOI,Tika,Openxml等,总结后感觉TIKA好使点(免费基本是一大原因),主要也是因为这个是ES推荐的一个文档抽取组件,工作中用过后比较合适,但是这东西是java的,但是我主要是C# 的选手,需要将java的包装一下才能用,用了一段时间后感觉还可以。

TIKA:https://tika.apache.org/

基本使用

因为我是C#选手,java在工作中用的都是非正规,maven这个东西现在让我拜托了IDE的依赖,所以我的IDE是VSCode,安装几个插件后就可以编码了。

Language Support for Java(TM) by Red Hatredhat.java预览版

Maven for Javavscjava.vscode-maven预览版

Project Manager for Javavscjava.vscode-java-dependency预览版

TIKA本身有很好的使用文档,我这里只说一下我用到的,TiKa提供了几个包供食用,分别应用于不同场景,我只需要它的内容抽取功能,就只引用了tika-parsers

  <dependency>
      <groupId>org.apache.tika</groupId>
      <artifactId>tika-parsers</artifactId>
      <version>1.25</version>
    </dependency>

基本的套路代码如下,使用的是通用抽取,不需要自己识别文档的类型,全部托管给TiKa处理(这里有个细节提一下就是文本的编码格式)。

文档搜索-TIKA

上图中可以看到文档的文本内容全部正常抽取出来,至于其它常用文档格式大家可以看TiKa的官方文档。

其核心代码如下:

	AutoDetectParser parser = new AutoDetectParser();
		AutoDetectParser parser = new AutoDetectParser();
	    BodyContentHandler handler = new BodyContentHandler();
	    Metadata metadata = new Metadata();
	    try {
	    	InputStream stream = new FileInputStream(new File(path)) ;
	        parser.parse(stream, handler, metadata);
	        return handler.toString();
	    }
	public String GetContent(String path) {
		AutoDetectParser parser = new AutoDetectParser();
	    BodyContentHandler handler = new BodyContentHandler();
	    Metadata metadata = new Metadata();
	    try {
	    	InputStream stream = new FileInputStream(new File(path)) ;
	        parser.parse(stream, handler, metadata);
	        return handler.toString();
	    }
	    catch(Exception e) {
	    	 e.printStackTrace();
	    }
	    
		return null;
	}

TiKa的能力现在也看到了,Java的项目当然可以直接拿来用,其它语言也有些对应封装,但是.Net平台上使用了一个收费组件封装,只能自己搞了。关于跨语言调用,每个语言平台基本上也都有自己的方案,我这里使用了一种外门邪道并且由于我对计算机系统原理知识的欠缺我甚至现在都不能肯定这个方案,只是在使用过程中,通过压测和正常线上使用没发现什么毛病就一直沿用了这个方案。

TiKa的C#封装

其原理就是通过标砖输入输出流,使用一个C#进程(通常就是使用此功能类库的项目)启动一个TiKa功能的Java进程,通过标准输入输出流进行功能调用(这个方案主要是解决了之前的TiKa进程是每次调用都会产生一个进程导致服务器在频繁文档操作时服务器压力过大),而当前方案则每个服务器只会启动一个TiKa进程,所有的调用都交由此进程排队处理。

文档搜索-TIKA

很好理解,调用方就像调用本语言类库功能一样,TiKa进程内部一直在使用标准输出流等待任务(每次调用就是一个数据包,格式固定),内部多线程处理每次条用即可,但是处理结果的返回就特殊一点,因为同样是流的形式并且返回顺序是不确定的即调用方来看就是异步的,这里C#进程我每次调用同样是一个任务队列,没调用一次就入队,此时要将当前调用方堵塞等待任务处理结果。

老三的古代
版权声明:本站原创文章,由 老三的古代2021-02-02发表,共计1899字。
转载提示:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)