所谓索引建立,就是对一堆文档的内容建立一个索引表,当然是传说中的倒排索引。
倒排索引:
倒排索引源于实际应用中需要根据属性的值来查找记录。这种索引表中的每一项都包括一个属性值和具有该属性值的各记录的地址。由于不是由记录来确定属性值,而是由属性值来确定记录的位置,因而称为倒排索引(inverted index)。带有倒排索引的文件我们称为倒排索引文件,简称倒排文件(inverted file)。
为了继续说明倒排文件,看看一下两个概念点:
(1)顺排文件
假设有网页P1,P2,……,Pn,给每个网页文件赋予一个编号Pid,给每个关键字赋予一个编号keyi,假设key是网页文件中的一个关键字,ni表示该关键字在网页文件中出现的次数,<hit1,hit2,…,hitn>表示该关键字在网页文件中的位置信息。首先将网页内容切分成一系列关键字:Pi={Key1,key2,…,keyn}。建立以下顺排文件:
P1={[n1,Key1(hit1,hit2,…,hitn)],…,[nx,keyi(hit1,hit2,…,hitx)] }
P2={[n1,Key1(hit1,hit2,…,hitn)],…,[nn,keyk(hit1,hit2,…,hitn)] }
…………
Pn={[n1,Key1(hit1,hit2,…,hitn)],…,[ny,keyj(hit1,hit2,…,hity)] }
例如,对以下两段文字进行顺排文件操作。
“随着经济的发展,人们对生活的品质要求越来越高。特别是在视觉欣赏方面,更是追求精益求精。如何把模糊的图像变得清晰,把暗淡的色彩变得色彩鲜艳是一个非常值得研究的课题。并且在数字电视、扫描仪、医疗图像、计算机视觉、卫星监测、航空摄像等方面对图像的清晰度有着广泛的需求。目前基于网格和密度的聚类方法已经渗透到各个领域,且得到了令人意想不到的效果。本文是将基于网格和密度的聚类方法运用到模糊图像中,从而对图像进行增色处理。”
“数字图像处理又称为计算机图像处理,它是指将图像信号转换成数字信号并利用计算机对其进行处理的过程。数字图像处理最早出现于20世纪50年代,当时的电子计算机已经发展到一定水平,人们开始利用计算机来处理图形和图像信息。数字图像处理作为一门学科大约形成于20世纪60年代初期。早期的图像处理的目的是改善图像的质量,它以人为对象,以改善人的视觉效果为目的。”
假设第一段文字是一个网页P1的全部内容,段首的起始位置为1。第二段文字是第二个网页P2的全部内容,段首的起始位置为1。
对网页进行自动分词,得到关键字以及关键字在网页文件中出现的位置信息。顺排文件的结果为:
P1={[1,经济(3)],[1,发展(6)],……,[2,视觉(26,93)],……,[5,图像(46,88,107,177,182)],……,[1,处理(189)]}
P2={[4,数字(1,29,48,101)],[8,图像(3,13,21,49,96,103,130,140)],……,[1,视觉(156)],……,[2,目的(135,161)]}
(2)倒排文件
顺排文件是以网页来索引关键字的,即形式为(网页→关键字),不符合搜索引擎的需要。因此,需进行倒排处理,以关键字来索引网页,即形式为(关键字→网页):
Keyi→{[Pid1,ni1(hit1,hit2,…,hitni1)],…,[Pidn,nin(hit1,hit2,…,hitnin)]}
对以上顺排文件中建立的两个实例网页P1和P2的顺排文件进行倒排,倒排文件的结果为:
经济→{[P1,1(3)]}
发展→{[P1,1(6)],[P2,1(74)]}
……
视觉→{[P1,2(26,93)],[P2,1(156)]}
……
图像→{[P1,5(46,88,107,177,182)],[P2,8(3,13,21,49,96,103,130,140)]}
……
综上所述,倒排文件的实现过程是:先得到顺排文件,然后根据顺排文件得到倒排文件,从而实现由关键字来索引网页。
再如,简单建立以下两个文件的倒排索引。
1.txt——我爱我的祖国,我爱五星红旗。
2.txt——我爱北京天安门。
则倒排文件的内容结构为:
假设格式为:keyword——DocumentName1(frequency1),DocumentName2(frequency2),……,DocumentName_n(frequency_n)
我——1.txt(3),2.txt(1) 爱——1.txt(2),2.txt(1) …… 五——1.txt(1) 北——2.txt(1)
|
Lucene是一款开源的索引/搜索开源框架,通过基于Lucene可以构建索引引擎,以下给出个对Html等网页文件进行索引的实例代码。
Index.java:
import java.io.File; import java.io.IOException; import java.util.List; import jeasy.analysis.MMAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.index.IndexWriter; import GEsearcher.index.html.HtmlParser; public class Index { //定义索引路径和数据路劲 private String indexpath; private String datapath; /* * 设置和获取函数 */ public String getDatapath() { return datapath; } public void setDatapath(String datapath) { this.datapath = datapath; } public String getIndexpath() { return indexpath; } public void setIndexpath(String indexpath) { this.indexpath = indexpath; } /* * 建立索引函数 */ public void DoIndex(boolean createnew) { FileManager filemanager=new FileManager(datapath);//获取索引材料库路径 List<File> filelist=filemanager.getFileList(); //todo //开始建立索引 Object[] files= filelist.toArray(); int i=0;//testing for(Object o:files) { File f=(File) o; String extname=getFileExtendsName(f); if(extname.equals("html") || extname.equals("htm") || extname.equals("asp")) { HtmlParser hp=new HtmlParser(f.getPath());//解析html文件 String title=hp.getTitle(); String url=hp.getUrl().replace("\\", "/"); String content=hp.getContent(); try { if(i==0 && createnew) { writeIndex(url, title, content, true); } else { writeIndex(url, title, content, false); } i++;//testing } catch (IOException e) { System.err.println("建立索引出错!"); e.printStackTrace(); } } else{ //其他文件格式的处理 } } System.out.println("建立html文件数为:"+i);//testing } /* * 判断文件扩展名 */ public String getFileExtendsName(File f) { String name=f.getName().toLowerCase(); int beginIndex=name.indexOf(".")+1; String res=name.substring(beginIndex); return res; } /* * 写索引 */ public void writeIndex(String url,String title,String content,boolean createnew) throws IOException { IndexWriter writer=new IndexWriter(indexpath, new MMAnalyzer(), createnew); writer.setUseCompoundFile(true); Document doc=new Document(); Field url_f=new Field("url", url, Field.Store.YES, Field.Index.NO); Field title_f=new Field("title", title, Field.Store.YES, Field.Index.TOKENIZED); Field content_f=new Field("content",content,Field.Store.YES,Field.Index.TOKENIZED); doc.add(url_f); title_f.setBoost(2f); //加大标题命中得分率 doc.add(title_f); doc.add(content_f); writer.setMaxFieldLength(1000); writer.addDocument(doc);//把文件写入索引 writer.close(); } }
其中, setDatapath(String datapath)是设置待建立索引的材料文件路径(文件夹),setIndexpath(String indexpath)是设置存放索引文件的的目录。writeIndex(String url,String title,String content,boolean createnew)方法是建立索引的核心程序单元,在建立索引过程中需要进行切词,这里使用jeasy.analysis.MMAnalyzer来实现。索引程序执行后,大致在存放索引的目录上生成如下图所示的文件。
至此,索引建立完毕!