Lucene初试——关于大文本建立索引和中文乱码以及QueryParser检索的一些体会

这几天因为一个小项目用到Lucene,于是去学习了一下,现在还有很多地方没有了解,先就我遇到的问题做下总结。

一、大文本建索引问题

我这里说的大文本,实际上也就200M左右的txt,或许不应该成为大文本,但是我在建索引时遇到200M左右的的确导致了内存溢出,报错误java.lang.OutOfMemoryError: Java heap space ,到网上查了很久,试了一些方法,比如修改JVM的运行参数等,都不行。我测试的机器为i5四核,4G内存,实测时可用内存1G多,按说对于200M的文本不应该可以接受吗?但是就是出现了内存溢出的情况。在对Lucene的机制还不了解的情况下,我想到了以下几种解决方案,一个是切割文本,将大文本首先预处理以下,分成小的文本,二是在建立索引时,对于大文本分段建立,比如读到50M往磁盘写一次,三是按行建立索引,比如一次读1w行。其实我觉得这些内在都是一个道理,就是一点点切分文本,只是实现方式稍有区别。

第一种情况我没有测试,觉得太麻烦,还要写个独立程序切割文本。第二种方式,我的代码逻辑是,读到一定大小的数据之后,就建立一个Document对象,然后设置setMaxBufferedDocs(n),我实测是10M的时候存一个Document,然后setMaxBufferedDocs(5),根据Lucene的官方文档,当内存中的缓存到达指定大小(我设置的200M)或者doc数目达到指定大小(也就是这里设置的5)时,就会触发一次往磁盘里写数据的操作。我觉的这样的话,内存里顶多只会有5*10=50M,大不了IO太频繁降低速度而已,至少得能跑。但实际测试过程中,发现跑了很久很久都没有把一个文本(170M)索引建好,按照我的理解,170M也就3、4次写操作不就可以了,但事实是很久没出现结果。于是我放弃了这种想法,没再去细究。

后来我用第三种方式测试了下,可行,而且效率还可以。思路是,每读1W行建立一个doc,我的这个文本比较特殊,2W行大概也就1m,然后设置setMaxBufferedDocs(100),这样反而可以。具体的数值设置可以根据自己环境来看,代码我也就不贴了,就是循环按行读取文本,1w次之后建立一个Document对象。

后来因为业务的需求,我又改成了1行建一个Document,然后setMaxBufferedDocs(2W),实测效率也可以。因为我检索时需要每一行的信息,所以只能按行读取。比如我的一行数据为“1052307934----huajun7089059----73.63.134.205----安徽省滁州市电信ADSL----2011年7月10日----14:28:24”,我搜索“安徽省滁州市”如果搜到了这条记录,那么我需要这一行的所有信息,如果不按每一行一个Document的话,比如我现在10行一个Document,那么噪音数据太多了。不知道Lucene有没有提供只提取我需要的信息的功能?要不然我就得自己写,从10行中找到我要的,那样也没有多大意义。

二、中文乱码问题

中文乱码真是无处不在。如果文件编码、系统编码、运行环境编码都一样应该不会出现乱码问题。如果知道文件的编码,一般

reader = new BufferedReader(new InputStreamReader(
							new FileInputStream(file), “gbk”));
类似这样的设置就可以解决,但是我的比较麻烦,因为源文件有的是gbk有的是utf-8。所以还得动态的去识别当前文件的编码。我查了下,识别文件编码好像不是那么容易,网上给了很多例子都不是很精确或者稳定,还好我找了一个,对于我的txt还是有用的,代码如下,共享下(非原创):
/**
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值