第三章 检索

3.1 搜索的简单实现

1.创建IndexReader

package com.mzsx.index;
 
import java.io.File;
import java.io.IOException;
 
importorg.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.IndexInput;
import org.apache.lucene.store.IndexOutput;
 
import com.mzsx.write.DirectoryConext;
 
public class IndexReaderContext {
         privatestatic IndexReader reader = null;
         privatestatic Directory directory=null;
         privateIndexReaderContext(){}
         
         publicstatic IndexReader getIndexReader(String fileName){
                   if(reader==null) {
                            directory=DirectoryConext.getDirectory(fileName);
                            synchronized(IndexReaderContext.class){
                                     if(reader==null) {
                                               try{
                                                        reader=IndexReader.open(directory,false);
                                               }catch (CorruptIndexException e) {
                                                        e.printStackTrace();
                                               }catch (IOException e) {
                                                        e.printStackTrace();
                                               }
                                     }
                            }
                            
                   }
                   returnreader;
         }
         publicstatic IndexReader getIndexReader(Directory dir){
                   if(reader==null) {
                            directory=dir;
                            synchronized(IndexReaderContext.class){
                                     if(reader==null) {
                                               try{
                                                        reader=IndexReader.open(directory,false);
                                               }catch (CorruptIndexException e) {
                                                        e.printStackTrace();
                                               }catch (IOException e) {
                                                        e.printStackTrace();
                                               }
                                     }
                            }
                            
                   }
                   returnreader;
         }
}

2.创建IndexSearcher

IndexSearcher searcher=new IndexSearcher(indexReader);

3.创建Term和TermQuery

Term term=new Term(field,name);
TermQuery termQuery=new TermQuery(term);

4.根据TermQuery获取TopDocs

TopDocs  topDocs= searcher.search(termQuery, num);
int length= topDocs.totalHits;
System.out.println("总共查询出来总数:"+length);

5.根据TopDocs获取ScoreDoc和ScoreDoc获取相应文档

ScoreDoc[] scoreDocs= topDocs.scoreDocs;
         for(ScoreDoc scoreDoc : scoreDocs) {
                   Documentdoc=searcher.doc(scoreDoc.doc);
                   System.out.println(doc.get("id")+ "---->"
                            +doc.get("filename") + "[" + doc.get("fullpath")
                            +"]-->\n" + doc.get("contents").substring(0, 50) );
         }

6.整体

//精确查询
         publicvoid searchByTerm(String field,String name,int num) {
                   try{
                            IndexSearchersearcher=new IndexSearcher(indexReader);
                            Termterm=new Term(field,name);
                            TermQuerytermQuery=new TermQuery(term);
                            TopDocs  topDocs= searcher.search(termQuery, num);
                            intlength= topDocs.totalHits;
                            System.out.println("总共查询出来总数:"+length);
                            ScoreDoc[]scoreDocs= topDocs.scoreDocs;
                            for(ScoreDoc scoreDoc : scoreDocs) {
                                     Documentdoc=searcher.doc(scoreDoc.doc);
                                     System.out.println(doc.get("id")+ "---->"
                                                        +doc.get("filename") + "[" + doc.get("fullpath")
                                                        +"]-->\n" + doc.get("contents").substring(0, 50) );
                            }
                   }catch (IOException e) {
                            e.printStackTrace();
                   }
         }

3.2 其他搜索Query

1. TermQuery—单个精确查询

//精确查询
         publicvoid searchByTerm(String field,String name,int num) {
                   try{
                            IndexSearchersearcher=new IndexSearcher(indexReader);
                            Termterm=new Term(field,name);
                            TermQuerytermQuery=new TermQuery(term);
                            TopDocs  topDocs= searcher.search(termQuery, num);
                            intlength= topDocs.totalHits;
                            System.out.println("总共查询出来总数:"+length);
                            ScoreDoc[]scoreDocs= topDocs.scoreDocs;
                            for(ScoreDoc scoreDoc : scoreDocs) {
                                     Documentdoc=searcher.doc(scoreDoc.doc);
                                     System.out.println(doc.get("id")+ "---->"
                                                        +doc.get("filename") + "[" + doc.get("fullpath")
                                                        +"]-->\n" + doc.get("contents").substring(0, 50) );
                            }
                   }catch (IOException e) {
                            e.printStackTrace();
                   }
         }

2.TermRangeQuery—查找字符串某个范围

public void searchByTermRange(String field,StringlowerTerm,String upperTerm,int num) {
                   try{
                            IndexSearchersearcher=new IndexSearcher(indexReader);
                            TermRangeQuery  range=new TermRangeQuery(field, lowerTerm,upperTerm, true, true);
                            TopDocs  topDocs= searcher.search(range, num);
                            intlength= topDocs.totalHits;
                            System.out.println("总共查询出来总数:"+length);
                            ScoreDoc[]scoreDocs= topDocs.scoreDocs;
                            for(ScoreDoc scoreDoc : scoreDocs) {
                                     Documentdoc=searcher.doc(scoreDoc.doc);
                                     System.out.println(doc.get("id")+ "---->"
                                                        +doc.get("filename") + "[" + doc.get("fullpath")
                                                        +"]-->\n" + doc.get("contents").substring(0, 50) );
                            }
                   }catch (CorruptIndexException e) {
                            //TODO Auto-generated catch block
                            e.printStackTrace();
                   }catch (IOException e) {
                            //TODO Auto-generated catch block
                            e.printStackTrace();
                   }
         }

3. NumericRangeQuery--查询某个数字的范围

public void searchByNumricRange(String field,longmin,long max,int num) {
                   try{
                            IndexSearchersearcher=new IndexSearcher(indexReader);
                            NumericRangeQuery  range=NumericRangeQuery.newLongRange(field,min, max, true, true);
                            TopDocs  topDocs= searcher.search(range, num);
                            intlength= topDocs.totalHits;
                            System.out.println("总共查询出来总数:"+length);
                            ScoreDoc[]scoreDocs= topDocs.scoreDocs;
                            for(ScoreDoc scoreDoc : scoreDocs) {
                                     Documentdoc=searcher.doc(scoreDoc.doc);
                                     System.out.println(doc.get("id")+ "---->"
                                                        +doc.get("filename") + "[" + doc.get("fullpath")
                                                        +"]-->\n" + doc.get("contents").substring(0, 50) );
                            }
                   }catch (CorruptIndexException e) {
                            e.printStackTrace();
                   }catch (IOException e) {
                            e.printStackTrace();
                   }
         }

4.PrefixQuery—前缀查询

public void searchByPrefix(String field,Stringvalue,int num) {
                   try{
                            IndexSearchersearcher=new IndexSearcher(indexReader);
                            PrefixQuery  range=new PrefixQuery(new Term(field,value));
                            TopDocs  topDocs= searcher.search(range, num);
                            intlength= topDocs.totalHits;
                            System.out.println("总共查询出来总数:"+length);
                            ScoreDoc[]scoreDocs= topDocs.scoreDocs;
                            for(ScoreDoc scoreDoc : scoreDocs) {
                                     Documentdoc=searcher.doc(scoreDoc.doc);
                                     System.out.println(doc.get("id")+ "---->"
                                                        +doc.get("filename") + "[" + doc.get("fullpath")
                                                        +"]-->\n" + doc.get("contents") );
                            }
                   }catch (CorruptIndexException e) {
                            e.printStackTrace();
                   }catch (IOException e) {
                            e.printStackTrace();
                   }
         }

5. WildcardQuery—通配符查询

//通配符模糊搜索
         //在传入的value中可以使用通配符:?和*,?表示匹配一个字符,*表示匹配任意多个字符
         publicvoid searchByWildcard(String field,String value,int num) {
                   try{
                            IndexSearchersearcher=new IndexSearcher(indexReader);
                            WildcardQuery  range=new WildcardQuery(newTerm(field,value));
                            TopDocs  topDocs= searcher.search(range, num);
                            intlength= topDocs.totalHits;
                            System.out.println("总共查询出来总数:"+length);
                            ScoreDoc[]scoreDocs= topDocs.scoreDocs;
                            for(ScoreDoc scoreDoc : scoreDocs) {
                                     Documentdoc=searcher.doc(scoreDoc.doc);
                                     System.out.println(doc.get("id")+ "---->"
                                                        +doc.get("filename") + "[" + doc.get("fullpath")
                                                        +"]-->\n" + doc.get("contents").substring(0,40) );
                            }
                   }catch (CorruptIndexException e) {
                            e.printStackTrace();
                   }catch (IOException e) {
                            e.printStackTrace();
                   }
         }

6.BooleanQuery—联合查询

public void searchByBoolean(int num) {
                   try{
                            IndexSearchersearcher=new IndexSearcher(indexReader);
                            BooleanQueryquery = new BooleanQuery();
                            query.add(newTermQuery(new Term("filename","凤凰台")), Occur.SHOULD);
                            query.add(newTermQuery(new Term("contents","用户")),Occur.SHOULD);
                            TopDocs  topDocs= searcher.search(query, num);
                            intlength= topDocs.totalHits;
                            System.out.println("总共查询出来总数:"+length);
                            ScoreDoc[]scoreDocs= topDocs.scoreDocs;
                            for(ScoreDoc scoreDoc : scoreDocs) {
                                     Documentdoc=searcher.doc(scoreDoc.doc);
                                     System.out.println(doc.get("id")+ "---->"
                                                        +doc.get("filename") + "[" + doc.get("fullpath")
                                                        +"]-->\n" + doc.get("contents").substring(0,40) );
                            }
                   }catch (CorruptIndexException e) {
                            e.printStackTrace();
                   }catch (IOException e) {
                            e.printStackTrace();
                   }
         }

7. PhraseQuery--短语检索

public void searchByPhrase(int num) {
                   try{
                            IndexSearchersearcher=new IndexSearcher(indexReader);
                            PhraseQueryquery = new PhraseQuery();
                            query.add(newTerm("filename","项目"));
                            query.setSlop(3);
                            query.add(newTerm("filename","系统"));
                            TopDocs  topDocs= searcher.search(query, num);
                            intlength= topDocs.totalHits;
                            System.out.println("总共查询出来总数:"+length);
                            ScoreDoc[]scoreDocs= topDocs.scoreDocs;
                            for(ScoreDoc scoreDoc : scoreDocs) {
                                     Documentdoc=searcher.doc(scoreDoc.doc);
                                     System.out.println(doc.get("id")+ "---->"
                                                        +doc.get("filename") + "[" + doc.get("fullpath")
                                                        +"]-->\n" + doc.get("contents").substring(0,40) );
                            }
                   }catch (CorruptIndexException e) {
                            e.printStackTrace();
                   }catch (IOException e) {
                            e.printStackTrace();
                   }
         }

8.FuzzyQuery--模糊匹配

public void searchByFuzzy(int num) {
                   try{
                            IndexSearchersearcher=new IndexSearcher(indexReader);
                            FuzzyQueryquery = new FuzzyQuery(new Term("contens","安全"),0.3f,0);
                            TopDocs  topDocs= searcher.search(query, num);
                            intlength= topDocs.totalHits;
                            System.out.println("总共查询出来总数:"+length);
                            ScoreDoc[]scoreDocs= topDocs.scoreDocs;
                            for(ScoreDoc scoreDoc : scoreDocs) {
                                     Documentdoc=searcher.doc(scoreDoc.doc);
                                     System.out.println(doc.get("id")+ "---->"
                                                        +doc.get("filename") + "[" + doc.get("fullpath")
                                                        +"]-->\n" + doc.get("contents").substring(0,40) );
                            }
                   }catch (CorruptIndexException e) {
                            e.printStackTrace();
                   }catch (IOException e) {
                            e.printStackTrace();
                   }
         }

3.3 QueryParser

1.QueryParser简介


Mike


默认域包含mike


Mike  john

Mike  OR  john


默认域包含mike或者john


+mike +address:zhaotong

Mike  AND  address:zhaotong


默认域即使mike并且address是zhaotong


id :2


Id域为2


Address:Kunming –desc:she

Address:Kunming AND NOT desc:she


Address是kunming并且desc不是she


(mike OR john) AND address:zhaotong


默认域是mike或者john 并且address是zhaotong


Desc: “she like”


Desc域是she like


desc:”happy girl”~5


查找happy和girl之间距离小于5的文档


J*


默认域是j开头


Johe~


模糊搜索johe


Id:[“1” TO “3”]


Id从1到3

2.QueryParser实例

public void searchByQueryParse(StringqueryContion,int num) {
                   try{
                            IndexSearchersearcher=new IndexSearcher(indexReader);
                            QueryParserparser = new QueryParser(Version.LUCENE_35,"contents",analyzer);
                            org.apache.lucene.search.Queryquery=parser.parse(queryContion);
                            TopDocs  topDocs= searcher.search(query, num);
                            intlength= topDocs.totalHits;
                            System.out.println("总共查询出来总数:"+length);
                            ScoreDoc[]scoreDocs= topDocs.scoreDocs;
                            for(ScoreDoc scoreDoc : scoreDocs) {
                                     Documentdoc=searcher.doc(scoreDoc.doc);
                                     System.out.println(doc.get("id")+ "---->"
                                                        +doc.get("filename") + "[" + doc.get("fullpath")
                                                        +"]-->\n" + doc.get("contents").substring(0,40) );
                            }
                   }catch (CorruptIndexException e) {
                            e.printStackTrace();
                   }catch (IOException e) {
                            e.printStackTrace();
                   }catch (ParseException e) {
                            e.printStackTrace();
                   }
         }
//测试代码
@Test
         publicvoid searchByQueryParse(){
                   SearchOperaopera=new SearchOpera("D:/luceneIndex/index", analyzer, true);
                   opera.searchByQueryParse("filename:[aTO z]",10);
                   //opera.searchByQueryParse("filename:{aTO g}",10);
                   //没有办法匹配数字范围(自己扩展Parser)
                   //opera.searchByQueryParse("size:[200TO 13000]",10);
                   
                   //完全匹配
                   //opera.searchByQueryParse("contents:\"完全是宠溺\"",10);
                   //距离为1匹配
                   //opera.searchByQueryParse("contents:\"完全宠溺\"~1",10);
                   //模糊查询
                   //opera.searchByQueryParse("contents:*",10);
         }

3.4 分页搜索

1.第一种方式:再查询

public void searchPage(String queryContion,intpageIndex,int pageSize){
       try{
           IndexSearchersearcher=new IndexSearcher(indexReader);
           QueryParserparser = new QueryParser(Version.LUCENE_35,"contents",analyzer);
           org.apache.lucene.search.Queryquery=parser.parse(queryContion);
           TopDocs  topDocs= searcher.search(query, 500);
           intlength= topDocs.totalHits;
           System.out.println("总共查询出来总数:"+length);
           ScoreDoc[]scoreDocs= topDocs.scoreDocs;
           intstart = (pageIndex-1)*pageSize;
           intend = pageIndex*pageSize;
           for(int i=start;i<end;i++) {
               Documentdoc=searcher.doc(scoreDocs[i].doc);
               System.out.println(doc.get("id")+ "---->"
                                  +doc.get("filename") + "[" + doc.get("fullpath")
                                  +"]-->\n" + doc.get("contents").substring(0,40) );
            }
         }catch (CorruptIndexException e) {
                 e.printStackTrace();
         }catch (IOException e) {
                e.printStackTrace();
         }catch (ParseException e) {
                e.printStackTrace();
         }
}
//测试代码
@Test
publicvoid searchPage(){
        SearchOperaopera=new SearchOpera("D:/luceneIndex/index", analyzer, true);
        opera.searchPage("filename:[aTO z]", 1, 3);
}

2.第二章方式:searchAfter

public void searchPageByAfter(String query,intpageIndex,int pageSize) {
                   try{
                            IndexSearchersearcher=new IndexSearcher(indexReader);
                            QueryParserparser = new QueryParser(Version.LUCENE_35,"content",analyzer);
                            Queryq = parser.parse(query);
                            //先获取上一页的最后一个元素
                            ScoreDoclastSd = getLastScoreDoc(pageIndex, pageSize, q, searcher);
                            //通过最后一个元素搜索下页的pageSize个元素
                            TopDocstds = searcher.searchAfter(lastSd,q, pageSize);
                            for(ScoreDocsd:tds.scoreDocs) {
                                     Documentdoc = searcher.doc(sd.doc);
                                     System.out.println(sd.doc+":"+doc.get("path")+"-->"+doc.get("filename"));
                            }
                            searcher.close();
                   }catch (org.apache.lucene.queryParser.ParseException e) {
                            e.printStackTrace();
                   }catch (IOException e) {
                            e.printStackTrace();
                   }
         }
    /**
          * 根据页码和分页大小获取上一次的最后一个ScoreDoc
          */
         privateScoreDoc getLastScoreDoc(int pageIndex,int pageSize,Query query,IndexSearchersearch) throws IOException {
                   if(pageIndex==1)returnnull;//如果是第一页就返回空
                   intnum = pageSize*(pageIndex-1);//获取上一页的数量
                   TopDocstds = search.search(query, num);
                   returntds.scoreDocs[num-1];
         }
//测试代码
@Test
         publicvoid searchPageByAfter(){
                   SearchOperaopera=new SearchOpera("D:/luceneIndex/index", analyzer, true);
                   opera.searchPageByAfter("filename:[aTO z]",1,3);
         }
时间: 2024-12-28 08:50:50

第三章 检索的相关文章

杨森翔:春节文化大观上编 第三章 春节古诗词 目录 第一节:春节诗词概述 一、 除夕诗词概述 二、元日诗词概述 三、 元宵诗词概述 第二节:春节古诗词拾萃

杨森翔:春节文化大观上编 第三章 春节古诗词 目录 第一节:春节诗词概述 一. 除夕诗词概述 二.元日诗词概述 三. 元宵诗词概述 第二节:春节古诗词拾萃 一.腊祭诗词 二.祭灶诗词 三.除夕诗词 四.元旦诗词 五.人日诗词 六.元宵诗词 第一节:春节古诗词概述 中国的春节,作为除旧迎新的节日,时间相当长,从年前的腊月二十三,天空中就似乎弥漫了节日的气息.这种节日的气氛,在保持传统风俗较好的地方,甚至会持续到二月二龙抬头的时候,但欢度春节的高潮,应该说是自除夕始一直到上元之夜.因此,历代歌咏和反

使用Micrisoft.net设计方案 第三章Web表示模式

第三章Web表示模式 体系结构设计者在设计第一个作品时比较精简和干练.在第一次设计时,并清除自己做什么,因此比较小心谨慎.第二个作品是最危险的一个作品,此时他会对第一个作品做修饰和润色,以及把第一次设计的边缘性设计思想都用在第二个作品,结果导致设计过头. 最初的Web很简单,只是有几个简单的Html页面组成,实现信息共享.随着业务的发展,需要根据业务来决定显示什么,于是开发了CGI编程,把大量的业务逻辑写到CGI中,然后输出到页面.随着发展,CGI编程模式受到了挑战,不能满足发展的需求,于是开发

【Oracle】第三章索引视图序列

第三章索引视图序列 序列是用来生成唯一,连续的整数的数据库对象.序列是用来自动生成主键或唯一键的值. CREATE SEQUENCE  sequence_name START WITH  integer INCREMENT BY  integer MAXVALUE   integer|nomaxvalue MINVALUE    integer|nominvalue CYCLE|NOCYCLE CACHE  integer|nocache; START WITH     指要生成的第一个序列号,

数据库期末考试复习题 第三章

作者 : Dolphin 原文地址:http://blog.csdn.net/qingdujun/article/details/27826439 一.填空题 1. SQL语言的数据定义功能包括①模式定义.②表定义.③视图和④索引的定义. 2. 视图是一个虚表,它是从①基本表或其他视图表中导出的表.在数据库中,只存放视图的②定义,不存放视图的③数据. 二.简答/综合 1. 简述在 SQL中使用视图的优点. 答:1)简化操作 2)从多角度看同一数据 3)视图给数据提供了一定逻辑独立性 4)视图给数

Android教材 | 第三章 Android界面事件处理(二)—— 杰瑞教育原创教材试读

 编者按 JRedu 杰瑞教育原创系列教材将于年后与大家正式见面.为更好的借鉴读者意见,我们将会陆续地在博客园推出一系列教材试读.我们也热忱的欢迎广大博友与我们互动,提出宝贵意见. 本篇博客将推出教材第三章第二部分的试读(传送门:第一部分),请大家继续提出宝贵意见,我们也将为积极互动的博友,免费提供我们的原创教材以及更多福利,也欢迎大家加入最下方QQ群与我们交流,谢谢大家! 3.5 系统设置事件处理 3.5.1onConfigurationChanged响应事件 在App开发过程中,有时候需要获

Java Persistence with MyBatis 3(中文版) 第三章 使用XML配置SQL映射器

关系型数据库和SQL是经受时间考验和验证的数据存储机制.和其他的ORM 框架如Hibernate不同,MyBatis鼓励开发者可以直接使用数据库,而不是将其对开发者隐藏,因为这样可以充分发挥数据库服务器所提供的SQL语句的巨大威力.与此同时,MyBaits消除了书写大量冗余代码的痛苦,它使使用SQL更容易. 在代码里直接嵌套SQL语句是很差的编码实践,并且维护起来困难.MyBaits使用了映射器配置文件或注解来配置SQL语句.在本章中,我们会看到具体怎样使用映射器配置文件来配置映射SQL语句.

构建之法前三章读后感

一. 软件作为一个产品,在提供用户使用前经历了许多工序,我们用工程的方式将开发软件的工序,过程加以工程化,系统化.成立了一套完整的体系后,有利于帮助我们开发软件,乃至于大型的系统. 软件具有一定的特殊性,使得软件工程师们做开发提升了一定的难度,但软件工程有助于软件系统的开发,帮助工程师们设计,构建,测试和维护软件.所以,软件工程的最终目的是帮助工程师们创造“足够好”的软件,提高软件的质量,用户满意度,可靠性,可维护性等. 第一章问题:怎么才算是一个真正的软件工程师? 二.   一个优秀的软件,通

0320 《构建之法》前三章观后感

第一章.为我们解释什么是软件,什么是软件工程,读完这章对这些概念有一定的认识这章让我明白,代码不能盲目的敲,好的软件并非两三天,并非一两个人就能赶出来的,需要大家的精诚合作.同时,在编写程序之前,还需要做一系列的分析.设计,要满足客户的需求,后续还要对软件进行测试.维护等.在这之前,我一直觉得能把程序运行,能有正确的结果,那就完成任务了,可这只是整个软件流程的一部分而已.看了邹老师的书,才知道其实创新有很多的方面,除了技术,还有商业思路,差异化等等,这些都给了我很大的感触,作为一名程序员,我们不

家庭作业——第三章

第三章家庭作业    3.69和3.70 3.69 A:long trace(tree_ptr tp)    {        long ret = 0;        while(tp != NULL)        {           ret = tp->val;           tp = tp->left;        }        return ret;    } B:作用是从根一直遍历左子树,找到第一个没有左子树的节点的值. 3.70 A:long traverse(t