Lucene是否能很好的支持元数据搜索
Lucene不是一个完整的全文索引应用,而是是一个用Java写的全文索引引擎工具包,它可以方便的嵌入到各种应用中实现针对应用的全文索引/检索功能,Lucene的目标是为各种中小型应用程序加入全文检索功能。(参考http://www.chedong.com/tech/lucene.html)
Lucene包含分词,索引,搜索等几个模块,支持单个关键字查询、范围查询、短语查询等,为构建全文搜索引擎提供了有力的支持。Lucene不仅支持对文件内容进行分析索引,也可以对文件的元信息进行分析索引,如可以通过Lucene为图书馆建立图书搜索引擎,此时可以将图书的作者、出版社、出版时间、图书编号等信息作为域以建立索引。
Linux下的find提供了针对文件元数据的查找功能,但其实现效率较低,需要遍历文件目录树,逐个匹配查找条件。那么能否利用Lucene对文件的元数据建立索引以加速元数据的查找呢?
全文搜索与元数据搜索的区别:
1. 用户进行全文检索的目的,通常只是找到需要的关键词的位置(如在浏览源代码时,需要找到某个函数出现的位置,可能对其进行编辑,如替换),可能用户得到第一个关键字出现的位置就达到了本次检索的目的,可能往后跳多个位置(Lucene通过将结果进行缓存,每次只缓存一部分搜索结果,如果用户需要后面的结果,则Lucene不断扩大缓存的大小,呈两倍方式增长),故如果前几个结果即可满足服务需求,则后面的结果则不用从硬盘中的索引读出。如在一个pdf文档中,搜索“中国”,此时,搜索引擎会跳到第一个出现“中国”的地方,用户发现查找的地方不满足需求时,会点击下一个,此时下一个位置的信息已经被Lucene缓存在内存中(缓存大小初始值可以设置),可以直接读出,如果用户点击下一个多次仍然没有找到需要的位置,而此时的位置信息已经超出了第一次缓存的大小,Lucene将缓存扩大至访问位置的2倍,并将不在内存中的内容读至缓存。对于多个文档的检索,Lucene对结果进行评分,并按得分进行排序,这样即使匹配到的内容有很多个,用户也不会感到面对庞大的搜索结果集束手无策。Lucene的对结果文档评分机制如下:Score = tf * idf * boost * lengthNorm
1) tf:被查询关键字在文档中出现的次数的平方根,关键字出现次数越多的文档得分越高;
2) idf:表示反转文档频率,默认为1 + log(numDocs / docFreq),即包含关键字的文档越少,包含此关键字的文档得分越高。
3) boost:激励因子(唯一可设置的单元),激励因子越高,文档得分越高。
4) lengthNorm:是由搜索的field的长度决定了,field的内容越长文档的分值越低,如搜索全文得到的结果比搜索某一属性得到的结果得分低。
2. 用户进行元数据检索的目的,通常是为了找到满足一定条件的某个文件(或一批文件)。首先由于基于元数据的关键字(uid,gid,访问时间等)数量有限,故搜索结果可能很多很多,如搜索所有者为jack的文档,搜索的结果可能一大堆,而且对于元信息,文档要么匹配有么不匹配,不存在得分排序的情况(即使按上面的得分计算也是不合理的)。假设对10w个文件建立了索引,并且每限定一个属性能过滤掉90%的文件(如系统中有10个用户,文件所有者均匀分布),查找时同时限定3个属性时,结果中还有100个文件文件,面对这100个属性,用户还是很为难,而这三个属性的限定可能包含范围查询(相当于一下限定了多个属性值),并且用户通常不会在搜索时限定多个属性,以我个人来说,find searchdir –name xxx。另外一个大的问题在于分词上,标准的分词机制显然不能满足元数据搜索的要求,关键的几点在于文件路径名的分词,时间信息的分词,大小信息(与时间信息有重叠的地方,当然可以进行转换,如将实际大小进行转换,后面加上K,M,G作为单位)。并且在进行范围查询时,Lucene默认使用字符串比较来确定范围,对于文件的size值,显然就很难支持范围查询,而对于大小属性来说,范围查询时必不可少的。
分析了这么多,我还是不能确定Lucene能否很好的支持元数据搜索,只有时间才能说明问题,但可以确定的是,Lucene要想做好元数据搜索,必须改进的地方包括:
1. 分词,分析元数据特性,进行合适的分词。
2. 范围查询,主要是时间范围和大小范围的支持。