lucene开发心得

写在前面:这个公司的搜索引擎项目终于差不多完工了,感谢有些人对我的支持和相信,由于是自己的第一个lucene的项目,所以整个过程中遇到了不少的问题和走了不少的弯路,不过好在撑了来,为了以后你们不走和我一样的弯路,也为了给自己做个记录,特此把一些心得写在这里,文笔不太好请见谅。

项目用的@lucene 是3.6版本的,很多特性是比较新的。

1、建立索引

建立索引开始的相关字段的相关属性是写了几个注解放在bean的字段上的,后来发现我们必须定义自己的javabean,不能很好的和系统中的其他模块整合,后来想到了xml,就还是可以引用已有的其他模块的相关javabean,然后相关的索引属性就放到了xml配置文件中,修改一下只要修改一下配置文件,灵活性很高,后来发现solr也用了相似的功能,呵呵,英雄所见略同。

项目的方案是每天将增量索引放到内存中,每天晚上刷新到磁盘中,因此往硬盘中写入索引的时候别忘了将你的内存Directory的IndexWriter关闭!否则可能导致你索引写入失败。IndexWriter不要初始化多次,一个Directory对应一个就好。

lucene索引查看工具luke是个好东西,但是在你的生产坏境上应该慎用此工具去查看你的索引,因为在快速往磁盘中写入索引的时候,可能会造成你的索引损坏!详细是会出现FileNotFound:XXXXXX.fnm文件,建议单独将索引文件拷贝出来进行查看和查询。

索引中保存的字段不宜太多,否则会造成查询速度的损耗,建议值索引或者分词相关字段,只保存一个数据的唯一标示符,然后再去数据库中获取详细信息。

如果要索引一个List里面的值,用空格拼接这些值,然后再分词索引,这样就将来就可以用类似数据库中的IN查询,建立索引的时候建议每个文档都放如一个简单的域用来保证可以查询出所有的数据,因为lucene并没有查询出所有数据的查询,例如可以放入一个QUERY_ALL的字段,值为1,然后每次查询都可以把QUERY_ALL:1带入到查询中去,如果项目要求一些字段支持isnull查询或者是isnotnull查询,请将空字段用null字符串代替,然后用field:null或者-field:null来查询,但是这个做法仅适用于不分词的常量字段。

2、索引查询

这个项目花费的大部时间实在查询上面,因为这个是直接面向用户的结果,所以直接体现了lucene的效果。

首先,对于Query的构建,不要使用QueryParser来做,QueryParser仅适用于调试阶段,它并没有SQL那么好的用处和性能,而且说不定就会有一个个的语法异常来找你,所以实际运行还是建议使用详细的Query子类来构建。

对于一些仅仅需要进行判断的字段请将字段匹配到的boost设置为0,否则根据类似标题、关键字查询出来的靠前的可能并不是你所想要的数据,有时候甚至标题并不包含你的关键字,但是排名甚至到了最前面去了。

对于手动构建Query,对于TermQuery是不能自动分词的,需要手动分词,对于分词存储的字段用你分词的分词请对字段值进行分词,生成多个TermQuery,分别用Should连接起来,但是不分词的请不要用分词器进行分词,那样一般会查询不出来数据的。

如果需要即时的搜索,应该在每次进行搜索之前调用IndexReader.isCurrent方法来判断索引是否是最新的,如果不是最新的则调用reopen方法打开,这是最节省性能的做法了,记得将以前打开的IndexReader关闭!

暂时写到这里了,如果有什么错误的地方,欢迎提出,如果你有什么好的使用经验也欢迎你一起来分享。

你可能感兴趣的:(java,Lucene)