全文索引-lucene,solr,nutch,hadoop之lucene

来源:互联网 发布:手机淘宝商品图片尺寸 编辑:程序博客网 时间:2024/04/29 19:38

         最先接触全文索引,还是在大学的时候,要给学校做一个搜索的项目,当初需求是能够提供类似百度的关键词搜索,但当时由于本身技术不行,虽然当时在网上找了一下资料,也看到了lucene,但当时学习的话,时间还是不够,而且有的难度,但当时已经知道可以用lucene来实现所需要的需求(当时项目中采用的方案是数据库多列合并like)。

       后来就开始学习lucene,才知道什么是全文索引,由于lucene对因为索引搜索非常好,但对中文,则还需要安装相应的中文词库。再后来就接触到了solr,solr可以说是lucene的商业封装,可以绝大部分情况下,直接拿来用,操作非常简单,其实solr就是对lucene的封装,但建议还是先从lucene开始学起,lucene是一个底层。后来进入公司后,直接用的就是solr,当成一个独立的搜索服务。再后来由于公司的需要,就开始了解到了nutch,如果说solr是对lucene的一次封装,那么nutch就是再次对solr的再次封装,不仅仅提供搜索服务,而且还提供网络爬虫的功能。科技的发展真是越来越快,随着需求的不断升级,比如在nutch进行网络爬虫时,如果对全网进行爬虫,那么毫无疑问会产生大量的索引文件,已经不仅仅是几G了,而且这个时候索引,检索的速度也是非常慢的,这个时候便有了hadoop这个号称云应用的hadoop便诞生了。可以说hadoop是现代性发展的产物,也是未来的法阵趋势,它使多台计算机真正的高并发协作工作来完成一个任务成为可能。

       下面就把我在学习lucene到solr以及nutch和hadoop以及工作的过程中所总结的资料分享一下,因为时间比较长了,留下的资料并不多,也不够全面。现在只是一个分享的过程而已。

       lucene

创建索引

    1 创建directory

       目录分好几中,其中RAMDirectory创建在内存中,FSDirectory为基于文件的索引,自己会选择最好的文件索引。

    2 创建IndexWriter

    3 创建索引的“数据库“,每一行为一个document,含有好几个field列。

 

搜索

     1 创建directory

     2 创建indexreader

     3 创建indexsearcher

     4 创建搜索的Query对象

           TermQuery 或者 QueryParse.parse(“”);

     5根据searcher搜索并返回topdocs对象

     6 根据topdocs创建sorcedoc对象

     7 根据searchersorcedoc获取具体的Document对象

     8 根据document对象获取需要的值

删除索引与恢复与合并

//参数是一个选项,可以是一个Query,也可以是一个term,term是一个精确查找的值

        //此时删除的文档并不会被完全删除,而是存储在一个回收站中的,可以恢复

writer.deleteDocuments(new Term("id","1"));

writer.commit();

相反:

//恢复时,必须把IndexReader的只读(readOnly)设置为false

        reader.undeleteAll();

或者

reader.deleteDocuments(new Term("id","1"));

强制删除:

writer.forceMergeDeletes();

 

//会将索引合并为2段,这两段中的被删除的数据会被清空

        //特别注意:此处Lucene在3.5之后不建议使用,因为会消耗大量的开销,

        //Lucene会根据情况自动处理的

writer.forceMerge(1);将多次索引合并一次索引

 

索引的更新

/*

         * Lucene并没有提供更新,这里的更新操作其实是如下两个操作的合集

         * 先删除之后再添加

       */

writer.updateDocument(new Term("id","1"), doc);

reader.numDeletedDocs()多了一个,可以证明

加权

doc.setBoost(0.5f); 排序大小

存储与索引

Field.Store.YES或者NO(存储域选项)

设置为YES表示或把这个域中的内容完全存储到文件中,方便进行文本的还原

设置为NO表示把这个域的内容不存储到文件中,但是可以被索引,此时内容无法完全还原(doc.get)

 

Field.Index(索引选项)(分词和索引是不一样的,先分词再索引

Index.ANALYZED:进行分词和索引,适用于标题、内容等

Index.NOT_ANALYZED:进行索引,但是不进行分词,如果身份证号,姓名,ID等,适用于精确搜索

Index.ANALYZED_NOT_NORMS:进行分词但是不存储norms信息,这个norms中包括了创建索引的时间和权值等信息

Index.NOT_ANALYZED_NOT_NORMS:即不进行分词也不存储norms信息

Index.NO:不进行索引

 

 

文件类型说明

.fnm 为存储域类型

.fdt .fdx为域的存储的值

.frq 为每个索引的次数,便于查询

.nrm norm,标分的信息

.prx  为偏移量

.tii  .tis 为索引里的所有索引信息

.del 删除的文件都在这里面

 

注意:在默认(增量索引)索引时,每次都会添加新的索引,即在原来的基础上增加索引,即以0,1,2顺序递增,因此搜索时也会出现多个相同的值

reader.numDocs() 有效的文档

reader.maxDoc()=reader.numDocs()+reader.numDeletedDocs()

sd.doc  文档的序号,整形

sd.socre=doc.getboost+匹配度

reader应该是单例模式,但当进行更改后应该重新初始化

reader = IndexReader.openIfChanged(reader);

totalhit 总共命中

searcher的分类

精确匹配查询  Query query = new TermQuery(new Term(field,name));

字符串范围的查询Query query = new TermRangeQuery(field,start,end,true, true);//是否包含最上面,最下面的

数字范围的查询  Query query = NumericRangeQuery.newIntRange(field,start, end,true,true);

前缀搜索 Query query = new PrefixQuery(new Term(field,value));

通配符搜索 Query query = new WildcardQuery(new Term(field,value));在传入的value中可以使用通配符:?和*,?表示匹配一个字符,*表示匹配任意多个字符

布尔搜索-多条件搜索

BooleanQuery query = new BooleanQuery();

           /*

            * BooleanQuery可以连接多个子查询

            * Occur.MUST表示必须出现

            * Occur.SHOULD表示可以出现

            * Occur.MUSE_NOT表示不能出现

            */

           query.add(new TermQuery(new Term("name","zhangsan")), Occur.MUST_NOT);

           query.add(new TermQuery(new Term("content","game")),Occur.SHOULD);

短语查询

PhraseQuery query = new PhraseQuery();

           //跳数,隔几个空格

           query.setSlop(3);

    //    query.add(new Term("content","pingpeng"));

           //第一个Term

           query.add(new Term("content","i"));

           //产生距离之后的第二个Term

           query.add(new Term("content","football"));

模糊查询

FuzzyQuery query = new FuzzyQuery(new Term("name","mase"),0.4f,0);

           System.out.println(query.getPrefixLength());//匹配前缀长度

           System.out.println(query.getMinSimilarity());//最小匹配长度

 

 

 

lucene-core-3.5.0.jar  是lucene的核心包,一般情况下只要有这个包就可以索引搜索了。

commons-io-2.1.jar   只是对文件进行操作的封装工具包。

lucene-memory-3.5.0.jar 是在lucene进行近实时搜索时用的缓存包。

lucene-highlighter-3.5.0.jar 是对lucene进行搜索后的结果进行关键字高亮的包。

mmseg4j-all-1.8.5-with-dic.jar 是中文插件包,可以让lucene支持中文分词,需要有词库(分词依赖)。

tika-app-1.0.jar 是对常用文件如excel,word,pdf 等的读取包。

这个还有一个比较重要的包lukeall-4.0.0-ALPHA.jar,这个包是个工具包,我们可以借助于这个包查看lucene的分词信息,见下图。