`
ahuaxuan
  • 浏览: 633529 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

深入浅出jackrabbit之十五 文档提取优化2.docx

阅读更多
/**
  *author:ahuaxuan
  *2009-10-22
*/

在上一篇文章中,我们讲到为什么要优化jackrabbit中的文档提取,同时也分析了进程模型和线程模型在分布式文档提取中的优劣。

在本文中,ahuaxuan将会介绍分布式文档提取的架构模型,以及它在整个非结构化数据库中的地位。 第二部分ahuaxuan将介绍几个用来提取文本的工具,然后将这些工具用在分布式文档提取中,以减轻jackrabbit的负担, 从这个角度看,本文是对上文的补充,这样从原因,到解决方案,以及所用到的技术工具基本上都涉及到了。

一, 分布式文档提取系统的结构模型。
首先来看一张文档提取系统部署的结构模型:

从上面一张图中可以看出每台lighttpd下面都挂着很多的flup, 之前我们讲过,文档提取系统是cpu密集型应用,而非io密集型应用,所以这里不用担心client->lighttpd->fastcgi这部分流程会出现瓶颈。

从进程模型上,我们可以得到另外一张图:



这个图表示,当一个提取任务发过来的时候, lighttpd会把请求交给flup处理,而flup会将这个任务分给一个子进程。这个子进程中有一些其他的字符串,比如catdoc, catppt等等,在文章的后半部分会介绍这些工具的作用。



而上面这张图是分布式文档提取系统在整个系统层次上的位置,其实它的主要功能就是分离计算,在下面这张图中,我们可以看到,index, extraction这样的高消耗cpu和内存的操作都从jackrabbit群组中分离出去了,将这些高消耗性能的非数值计算分离出去可以有效的提高主应用程序的稳定性和扩展性。


看过这三幅图之后,相信大家对分布式文档提取的在整套系统中的地位已经有了一定的了解。下面我们来看看一些常见的文档提取工具。

Xpdf(GNU General Public License (GPL), version2)
Xpdf是用来提取pdf中text的工具

pyPdf(modified BSD license)
pyPdf用来提取pdf中text的工具

Htmllib
用来提取html中的文本

UnRtf(GNU)
用来其他RTF文件中的文本

pyRtf(GPL & LGPL)
pyRTF目前只支持生成rtf文件

Catdoc(GNU Public License)
用来提取word2003的文本

Catppt(GNU Public License)
用来提取ppt2003中的文本

Xls2csv(GNU Public License)
将xls转成csv, 而csv其实就是纯文本,对于做索引来说csv和纯文本基本没有区别

others for 2003
还有就是一些收费的,就不帮他们做广告了

openxmllib(lxml)
GNU General Public License, Version 2.0 (GPL).
   Openxmllib是用来提取office2007中word, excel, ppt中的纯文本的,不过需要注意的是它有一个缺陷,它提取出来的文本是无序的,也就是句子的顺序会被打乱,如果你只是做索引,那么这个特性对你来说没有影响,但是如果你想把提取之后的文档保存起来,以后作高亮只用,那么就必须扩展一下openxmllib,还好它比较简单,ahuxuan只用了个把小时就完成了改造。

说到这里分布式文档提取也就基本结束了,当然ahuaxuan并没有把一些细节全盘托出,因为考虑到在完成这项改造之前,同学们必须了解jackrabbit已有的文档提取逻辑,而如果已经了解了那些逻辑,那么我也没有必要将这些细节全盘托出了。阿弥陀佛。


TO BE CONTINUE
  • 大小: 34.5 KB
  • 大小: 19.8 KB
  • 大小: 21.3 KB
0
0
分享到:
评论
12 楼 fh2002 2010-08-26  
用xpath能查询时间段么?
11 楼 ahuaxuan 2010-02-08  
smiky 写道
ahuaxuan 写道
smiky 写道
如果将文件保存在子节点中,根据文件属性查询的时候就会不方便了吧

这种方式肯定是可行的,因为我们就是这样作的,如果你的查询条件在file, 和file的子节点上,你可以用这种查询语句:
//xxx/xxxx/xxx//element(*, xxxx:file)[ jcr:contains(@name, 'keyword')"
+ " or jcr:contains(child::jcr:content, 'keyword')]/jcr:content/rep:excerpt(.)

这里的jcr:content就是file节点的名称.你可以通过这种方式来做查询,但是如果你没有查文档本身内容的需求,那你就不需要查询file的子节点.直接在file节点上查询就可以来


对于查询,一个文件本身有多个属性,如果查询界面做成象google那样只有一行,那么查询时如何知道用户输入的是那个属性的值?jcr:contains(@name, 'keyword')这里如果我没理解错的话是指用name属性来查,那么文件有多个属性,而查询界面又不能指定用户是使用那个属性来查,何解?

这个可以使用 . 操作,比如说jcr:contains(., 'keyword'),这表示其中只要有一个属性包含keyword这个关键词就满足匹配。
10 楼 smiky 2010-02-08  
ahuaxuan 写道
smiky 写道
如果将文件保存在子节点中,根据文件属性查询的时候就会不方便了吧

这种方式肯定是可行的,因为我们就是这样作的,如果你的查询条件在file, 和file的子节点上,你可以用这种查询语句:
//xxx/xxxx/xxx//element(*, xxxx:file)[ jcr:contains(@name, 'keyword')"
+ " or jcr:contains(child::jcr:content, 'keyword')]/jcr:content/rep:excerpt(.)

这里的jcr:content就是file节点的名称.你可以通过这种方式来做查询,但是如果你没有查文档本身内容的需求,那你就不需要查询file的子节点.直接在file节点上查询就可以来


对于查询,一个文件本身有多个属性,如果查询界面做成象google那样只有一行,那么查询时如何知道用户输入的是那个属性的值?jcr:contains(@name, 'keyword')这里如果我没理解错的话是指用name属性来查,那么文件有多个属性,而查询界面又不能指定用户是使用那个属性来查,何解?
9 楼 ahuaxuan 2010-02-07  
smiky 写道
如果将文件保存在子节点中,根据文件属性查询的时候就会不方便了吧

这种方式肯定是可行的,因为我们就是这样作的,如果你的查询条件在file, 和file的子节点上,你可以用这种查询语句:
//xxx/xxxx/xxx//element(*, xxxx:file)[ jcr:contains(@name, 'keyword')"
+ " or jcr:contains(child::jcr:content, 'keyword')]/jcr:content/rep:excerpt(.)

这里的jcr:content就是file节点的名称.你可以通过这种方式来做查询,但是如果你没有查文档本身内容的需求,那你就不需要查询file的子节点.直接在file节点上查询就可以来
8 楼 smiky 2010-02-06  
如果将文件保存在子节点中,根据文件属性查询的时候就会不方便了吧
7 楼 bupt04406 2009-11-17  
ahuaxuan 写道
bupt04406 写道
,就是把一些共有的文件属性提取出来,放到父节点,而文件保存在子节点上,而其私有的或者不相同的属性放在下面的子节点上。

私有的属性其实放在父节点上也没有关系,这种模型主要是考虑到修改属性的时候带来的重新索引的开销,文档重新索引之前不是需要做提取操作的,很耗cpu,所以最好是属性的修改和文档本身的修改是发生在不同的节点上,这样属性的修改只影响父节点,子节点不会被重新做提取和索引。其实这样问题的根源在于lucene不支持document的update,所以任何修改都是先delete,再add,于是如果文档和属性在同一个节点上,那么修改文档的属性也会导致文档被重新提取, 重新做索引。


嗯,知道了,谢谢,哈哈
6 楼 ahuaxuan 2009-11-17  
rain2005 写道
这么感觉这个东西和nutch,hadoop差不多呢。

不一样的,hadoop是做分布式计算和存储,jcr是做内容(文档之类)的存储和管理,以及查询,我们可以把jcr看作是一个数据库。只是这个数据库不能定义表。然后所有的记录都存在一颗多叉树上。
5 楼 rain2005 2009-11-17  
这么感觉这个东西和nutch,hadoop差不多呢。
4 楼 ahuaxuan 2009-11-17  
bupt04406 写道
,就是把一些共有的文件属性提取出来,放到父节点,而文件保存在子节点上,而其私有的或者不相同的属性放在下面的子节点上。

私有的属性其实放在父节点上也没有关系,这种模型主要是考虑到修改属性的时候带来的重新索引的开销,文档重新索引之前不是需要做提取操作的,很耗cpu,所以最好是属性的修改和文档本身的修改是发生在不同的节点上,这样属性的修改只影响父节点,子节点不会被重新做提取和索引。其实这样问题的根源在于lucene不支持document的update,所以任何修改都是先delete,再add,于是如果文档和属性在同一个节点上,那么修改文档的属性也会导致文档被重新提取, 重新做索引。
3 楼 bupt04406 2009-11-17  
,就是把一些共有的文件属性提取出来,放到父节点,而文件保存在子节点上,而其私有的或者不相同的属性放在下面的子节点上。
2 楼 ahuaxuan 2009-11-17  
bupt04406 写道
请教个问题,如果有很多文件,如视频,音频,图片等等,存储这些文件是,都是用一个node来存储一个文件,node下面有表示文件内容的property,有表示该文件信息即元数据的property,不知道如果每个node的property都很多效果如何,如一个音频,有表示文件名的property,有表示文件大小,文件创建时间,文件修改时间,文件格式,音频的演唱者、专集、年月、流派、注释等等信息,这些都是一个个property来存储,这样每个文件property很多,加上文件数也很多,不知道这样效率等如何,是这样使用jackrabbit吗?

是的,可以这样使用,当然也可以有其他使用的方式,比如说父节点中保存所有的属性,文件保存在它唯一的字节点上,这样做的好处是更新属性的时候,子节点无需变动,如果你处理office文档,或者pdf之类的时候,这种模型更为有效,它能避免无谓的文档提取的消耗。
1 楼 bupt04406 2009-11-16  
请教个问题,如果有很多文件,如视频,音频,图片等等,存储这些文件是,都是用一个node来存储一个文件,node下面有表示文件内容的property,有表示该文件信息即元数据的property,不知道如果每个node的property都很多效果如何,如一个音频,有表示文件名的property,有表示文件大小,文件创建时间,文件修改时间,文件格式,音频的演唱者、专集、年月、流派、注释等等信息,这些都是一个个property来存储,这样每个文件property很多,加上文件数也很多,不知道这样效率等如何,是这样使用jackrabbit吗?

相关推荐

Global site tag (gtag.js) - Google Analytics