Lucene全文检索入门体验

Lucene是Apache开源的全文检索框架, 是单纯的搜索工具, 简单易用. 如今已经出到5.2.1的版本, 只需在项目中导入必需的几个jar包就能使用. 使用的过程能够归纳为,java

1)  创建索引网络

2) 搜索查找, 获取搜索结果app

 

这里咱们一块儿先来学习几个会用到的核心类:框架


Directory工具

该类在Lucene中用于描述索引存放的位置信息. 好比:学习

 

[java] view plain copy测试

  1. Directory dir = FSDirectory.open(Paths.get("c:\\lucene\\index"));   

其中" c:\\lucene\\index" 是存放索引的文件夹位置.
 搜索引擎

 

Analyzerspa

Analyzer是Lucene的分词器, 能够说是分词解析技术也能够说是搜索引擎的核心技术之一. 一句话被断句分词分析, .使搜索结果更智能更精准. 中文词库分词, 可使用IKAnalyzer等中文分词工具包..net

 

Analyzer这个类的做用要结合IndexWriterConfig和IndexWriter这两个类去认识:

IndexWriterConfig, 从类名可知, 是一个保存参数配置的类, 用于生成IndexWriter. 好比:

 

[java] view plain copy

  1. IndexWriterConfig iwc = new IndexWriterConfig(luceneAnalyzer);    
  2.             iwc.setOpenMode(OpenMode.CREATE);    
  3.             IndexWriter indexWriter = new IndexWriter(dir,iwc);   


setOpenMode(...) 设置了IndexWriter的打开方式.

 

固然还有更多的参数设置, 能够参考这篇文章哦. IndexWriterConfig配置参数说明

 

上面的三行代码也是建立一个IndexWriter的过程. (dir这个参数就是第一个说起的类Directory.)

IndexWriter 是创建索引的核心类. 若是你也知道Android的SharePreference, SharePreference里面有一个Editor类. IndexWriter 就是相似Editor这样的类, 能够针对索引进行添加(建立新的索引并写入索引文档中), 删除(从索引文档删除索引)和更新(更新索引文档中的索引) 操做. 顺便提一下, Lucene的索引, 会生成对应的索引文档, 因此最好创建文件夹专门存放这些文档.

 

Document

Document类顾名思义是"文件"类, 其实它是用来存放Field集合. 能够理解为存放文件, 通常都是可转换的文本信息, 好比doc, txt等等. 当把用于被查找的文件信息加入Document后, 再经过

 

[java] view plain copy

  1. indexWriter.addDocument(document);  

这样就添加了一个索引. 来到这里, 也许你会想到, 之后要查询直接先来索引这里就好了.

 

 

IndexReader

对应于IndexWriter, 就有IndexReader. 建立方法 :

 

[java] view plain copy

  1. IndexReader reader = DirectoryReader.open(FSDirectory.open(Paths.get(index)));  

 

它只读取索引文档. 而后交给检索工具IndexSearcher 去完成查找. 根据传进Query检索条件进行检索查找后, 会获得一个ScoreDoc类型的结果集, 而后读取它的Document信息, 就能获取检索结果的具体信息, 好比关键字包含在哪些内容中, 已经这些内容文档的存放路径等等. 这样就算是完成整个检索过程了.

 

OK, 下面咱们来简单的例子体验下, 有兴趣能够本身去看文档详细了解哦.

注: 本例子的代码来自网络, 是很简单易懂的例子, 因此就再也不另外写了, 这里只是体验学习, 咱们直接学习别人的. 额, 原做者不知道是谁了, 在这里感谢一下. 

通过上面的关键类的介绍, 相信看下面例子的代码会容易懂不少了, So 直接上代码.

1) 创建索引文档. 

随便在本地创建一个文件夹, 好比C盘根目录建立index文件夹. 路径就是 C:\index . 而要检索的内容文档放在 C盘根目录的source文件夹中, 路径就是C:\source .

 

[java] view plain copy

  1. public class CreateIndex {  
  2.      public static void main(String[] args) throws Exception {      
  3.          /* 指明要索引文件夹的位置,这里是C盘的source文件夹下 */      
  4.         File fileDir = new File("C:\\source");      
  5.           
  6.          /* 这里放索引文件的位置 */      
  7.          //File indexDir = new File("c:\\index");   
  8.          String indexPath = "c:\\index";  
  9.            
  10.          // Directory dir = FSDirectory.open(indexDir);    //v3.6.0  
  11.          Directory dir = FSDirectory.open(Paths.get(indexPath));    
  12.            
  13.          //Analyzer luceneAnalyzer = new StandardAnalyzer(Version.LUCENE_3_6_0);   
  14.          Analyzer luceneAnalyzer = new StandardAnalyzer();  
  15.          IndexWriterConfig iwc = new IndexWriterConfig(luceneAnalyzer);    
  16.          iwc.setOpenMode(OpenMode.CREATE);    
  17.          IndexWriter indexWriter = new IndexWriter(dir,iwc);      
  18.          File[] textFiles = fileDir.listFiles();      
  19.          long startTime = new Date().getTime();      
  20.                
  21.          //增长document到索引去      
  22.          for (int i = 0; i < textFiles.length; i++) {      
  23.              if (textFiles[i].isFile()      
  24.                     ) {      
  25.                  System.out.println("File " + textFiles[i].getCanonicalPath()      
  26.                          + "正在被索引....");      
  27.                  String temp = FileReaderAll(textFiles[i].getCanonicalPath(),      
  28.                          "GBK");      
  29.                  System.out.println(temp);      
  30.                  Document document = new Document();      
  31.                  
  32.                  Field FieldPath = new StringField("path", textFiles[i].getPath(), Field.Store.YES);  
  33.                  Field FieldBody = new TextField("body", temp, Field.Store.YES);      
  34.                  document.add(FieldPath);      
  35.                  document.add(FieldBody);      
  36.                  indexWriter.addDocument(document);      
  37.              }      
  38.          }      
  39.          indexWriter.close();      
  40.                
  41.          //测试一下索引的时间      
  42.          long endTime = new Date().getTime();      
  43.          System.out      
  44.                  .println("这占用了"      
  45.                          + (endTime - startTime)      
  46.                          + " 毫秒来把文档增长到索引里面去!"      
  47.                          + fileDir.getPath());      
  48.      }      
  49.        
  50.      public static String FileReaderAll(String FileName, String charset)      
  51.              throws IOException {      
  52.          BufferedReader reader = new BufferedReader(new InputStreamReader(      
  53.                  new FileInputStream(FileName), charset));      
  54.          String line = new String();      
  55.          String temp = new String();      
  56.                
  57.          while ((line = reader.readLine()) != null) {      
  58.              temp += line;      
  59.          }      
  60.          reader.close();      
  61.          return temp;      
  62.      }      
  63.       
  64. }  


2) 执行检索查找的类:

 

 

[java] view plain copy

  1. public class ExecuteQuery {  
  2.     public static void main(String[] args) throws  IOException, ParseException  {    
  3.         String index="c:\\index";//搜索的索引路径    
  4.      //   IndexReader reader=IndexReader.open(FSDirectory.open(Paths.get(index));    //v3.6.0的写法  
  5.         IndexReader reader = DirectoryReader.open(FSDirectory.open(Paths.get(index)));  
  6.         IndexSearcher searcher=new IndexSearcher(reader);//检索工具    
  7.         ScoreDoc[] hits=null;    
  8.         String queryString="好";  //搜索的索引名称    
  9.         Query query=null;    
  10.         Analyzer analyzer= new StandardAnalyzer();    
  11.         try {    
  12.             //QueryParser qp=new QueryParser(Version.LUCENE_3_6_0,"body",analyzer);//用于解析用户输入的工具   v3.6.0  
  13.             QueryParser qp=new QueryParser("body",analyzer);//用于解析用户输入的工具  
  14.             query=qp.parse(queryString);    
  15.         } catch (ParseException e) {    
  16.             // TODO: handle exception    
  17.         }    
  18.         if (searcher!=null) {    
  19.             TopDocs results=searcher.search(query, 10);//只取排名前十的搜索结果    
  20.             hits=results.scoreDocs;    
  21.             Document document=null;    
  22.             for (int i = 0; i < hits.length; i++) {    
  23.                 document=searcher.doc(hits[i].doc);    
  24.                 String body=document.get("body");    
  25.                 String path=document.get("path");    
  26.                 String modifiedtime=document.get("modifiField");    
  27.                 System.out.println("BODY---"+body+"      ");     
  28.                 System.out.println("PATH--"+path);     
  29.             }    
  30.             if (hits.length>0) {    
  31.                 System.out.println("输入关键字为:"+queryString+","+"找到"+hits.length+"条结果!");    
  32.                     
  33.             }    
  34.           //  searcher.close();    
  35.             reader.close();    
  36.         }    
  37.     }    
  38.       
  39. }  


例子里面是搜索"好"字. 效果如图:

 

而后修改一下内容文档:

搜索"努力"

中文搜索ok~ 

相关文章
相关标签/搜索