一、Lucene的基础(2017-05-11 10:40:46)

1、Lucene的下载

API的下载:http://pan.baidu.com/s/1nvLTG0L

视频资料下载:http://pan.baidu.com/s/1gfOifeF

2、Lucene的使用

Lucene的学习与总结Lucene的学习与总结
        IndexWriter writer = null;
        try {
            writer = new IndexWriter(directory, new IndexWriterConfig(Version.LUCENE_35, new StandardAnalyzer(Version.LUCENE_35)));
            Document doc = null;
            for(int i=0;i<ids.length;i++){
                doc = new Document();
                doc.add(new Field("id",ids[i],Field.Store.YES,Field.Index.NOT_ANALYZED_NO_NORMS));
                doc.add(new Field("email",emails[i],Field.Store.YES,Field.Index.NOT_ANALYZED));
                doc.add(new Field("content",contents[i],Field.Store.NO,Field.Index.ANALYZED));
                doc.add(new Field("name",names[i],Field.Store.YES,Field.Index.NOT_ANALYZED_NO_NORMS));
                //存储数字
                doc.add(new NumericField("attach",Field.Store.YES,true).setIntValue(attachs[i]));
                //存储日期
                doc.add(new NumericField("date",Field.Store.YES,true).setLongValue(dates[i].getTime()));
                //加权操作
                String et = emails[i].substring(emails[i].lastIndexOf("@")+1);
                writer.addDocument(doc);
            }
        } catch (CorruptIndexException e) {
            e.printStackTrace();
        } catch (LockObtainFailedException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if(writer != null) writer.close();
            } catch (CorruptIndexException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        
    
建立索引
Lucene的学习与总结Lucene的学习与总结
/**
     * 搜索
     */
    public void searcher(){
        try {
            //1、创建Directory
            Directory directory = FSDirectory.open(new File("d:/import/studytool/Lucene/index01"));
            //2、创建IndexReader
            IndexReader reader = IndexReader.open(directory);
            //3、根据IndexReader创建IndexSearcher
            IndexSearcher searcher = new IndexSearcher(reader);
            //4、创建搜索的Query
            //创建parser来确定要搜索文件的内容,第二个参数表示搜索的域
            QueryParser parser = new QueryParser(Version.LUCENE_35, "content", new StandardAnalyzer(Version.LUCENE_35));
            //创建query,表示搜索域为content中包含come的文档
            Query query = parser.parse("come");
            //5、根据Seacher搜索并返回TopDocs
            TopDocs tds = searcher.search(query, 10);
            //6、根据TopDocs获取ScoreDoc对象
            ScoreDoc[] sds = tds.scoreDocs;
            for(ScoreDoc sd : sds){
                //7、根据seacher和ScordDoc对象获取具体的Document对象
                Document d = searcher.doc(sd.doc);
                //8、根据Document对象获取需要的值
                System.out.println(d.get("filename")+"["+d.get("path")+"]");
            }
            //9、关闭reader
            reader.close();
        } catch (CorruptIndexException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
搜索

3、基本实例

4、系统架构

5、索引过程的核心类

5.1、IndexWriter

5.2、Directory

5.3、Analyzer

5.4、Document

5.5、Field

6、搜索过程的核心类

6.1、IndexSearcher

6.2、Term

6.3、Query

6.4、TermQuery

6.5、TopDocs

6.6、SocreDoc

二、索引的建立

1、基本概念

2、索引过程

3、索引建立步骤

3.1、创建Directory

Lucene的学习与总结

3.2、创建Writer

Lucene的学习与总结

3.3、创建文档并且添加索引

文档和域的概念很重要

  文档相当于表中的每一条记录,域相当于表中的每一个字段

 Lucene的学习与总结

3.4、查询索引的基本信息

使用IndexReader进行查询

Lucene的学习与总结

3.5、删除和更新索引

1、删除

Lucene的学习与总结

可能得到结果:

Lucene的学习与总结

2、恢复

Lucene的学习与总结

3、强制删除(不建议使用)

Lucene的学习与总结

4、优化和合并(不建议使用)

Lucene的学习与总结

5、更新索引

Lucene的学习与总结

4、域选项

4.1、索引域选项

使用Field.Index.*来进行操作

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

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

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

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

Index.NO:不进行索引

4.2、存储域选项

Field.Store.*

YES:(可以还原)

  将会存储域值,原始字符串的值会保存在索引,以此可以进行相应的恢复操作,对于主键,标题可以是这种方式存储

NO:(无法完全还原),可以索引

  不会存储域值,通常与Index.ANAYLIZED合起来使用,索引一些如文章正文等不需要恢复的文档

4.3、最佳实践

NOT_ANALYZED_NOT_NORMS YES 标志符(主键、文件名),电话号码,身份证号,姓名,日期
ANAYLZED YES 文档标题和摘要
ANAYLZED NO 文档正文
NO YES 文档类型,数据库主键(不进行索引)
NOT_ANALYZED NO 隐藏关键字

.fnm    保存的是域选项的信息

.fdt/.fdx  保存的是域Store.YES的信息

.frq     保存的是域选项中词出现的次数(搜索"java"这个词,这个文件就会保存每个文章中java出现的次数)

.norm   保存一些评分信息

.prx    偏移量

.tii/.tis   索引里面所有的索引信息

5、其他知识

5.1、对数字和日期进行索引

Lucene的学习与总结

5.2、常用的Directory

FSDirectory.open会根据当前的运行环境打开一个最合理的基于File的Directory

new RAMDirectory会从内存中打开directory,好处是速度快,缺点是无法持久化

5.3、IndexReader和IndexWriter的生命周期

 

 三、搜索功能

1、搜索的简单实现(TermQuery)

1.1、创建IndexReder

public IndexSearcher getSearcher() {
        try {
            if(reader == null) {
                reader = IndexReader.open(directory);
            } else {
                IndexReader tr = IndexReader.openIfChanged(reader);
                if(tr != null){
                    reader.close();
                    reader = tr;
                }
            }
            return new IndexSearcher(reader);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

 

1.2、创建IndexSearcher

return new IndexSearcher(reader);

 

1.3、创建Term和TermQuery

IndexSearcher searcher = getsercher();
Query query = new TermQuery(new Term(field,name));

 

 

1.4、根据TermQuery获取TopDocs

TopDocs tds = searcher.search(query,num);
System.out.println(“一共查询了:”+tds.totlHits);
tds.totlHits是总记录数,和传出的num没有任何关系

 

1.5、根据TopDocs获取ScoreDoc

for(ScoreDoc sd : tds.scoreDocs) {
    Document doc = searcher.doc(sd.doc);
}

 

1.6、根据ScoreDoc获取相应文档

for(ScoreDoc sd : tds.scoreDocs) {
    Document doc = searcher.doc(sd.doc);
}

 

2、其他搜索(Query) 

2.1、TermRangerQuery(范围查找)

IndexSearcher searcher = getSearcher();
//field:要查询的field  start:开始字符  end:结束字符  TRUE:开区间 Query query = new TermRangeQuery(field,start,end,true,true); TopDocs tds = searcher.search(query,num); System.out.println(“一共查询了:”+tds.totlHits); for(ScoreDoc sd : tds.scoreDocs) { Document doc = searcher.doc(sd.doc); System.out.println(); }

2.2、NumericRange(查询某个数字的范围)

Query query = NumericRangeQuery.newIntRange(field,start,end,true,true);
TopDocs tds = searcher.search(query,num);
System.out.println("一共查询了:"+tds.totalHits);

 

2.3、PreflxQuery(前缀搜索)

//此时value的值就是通过前缀来匹配
Query query = new PrefixQuery(new Term(field,value));

 

2.4、WildcardQuery(通配符搜索*)

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

 

2.5、BooleanQuery

BoolenQuery可以连接多个子查询
Occur.Must表示必须出现
Occur.SHOULD表示可以出现
Occur.MUST_NOT表示不能出现
//可以连接多个文件
BooleanQuery query = new BoolenQuery();
query.add(new TermQuery(new Term("name","zhangsan")),Occur.Must);
query.add(new TermQuery(new Term("content","like")),Occur.Must);

 

2.6、PhraseQuery(短语查询,不能用于中文搜索)

PhraseQuery query = new PhraseQuery();
query.setSlop(1);
query.add(new Term("content","I"));
query.add(new Term("content","football");

 

2.7、FuzzyQuery(模糊查询)

Query query = new FuzzyQuery(new Term(“name”,"Make"),0.4f,0);

 3、Queryparser

3.1、制定项查找

3.2、制定范围查找

3.3、搜索数字和日期范围

3.4、前缀查找

3.5、布尔查询

4、分页搜索


 

四、分页


 

五、高级搜索

1、搜索排序

2、搜索过滤

相关文章: