Lucene02---Lucene入门与Demo

来源:互联网 发布:淘宝运营和直通车车手 编辑:程序博客网 时间:2024/06/07 13:02
 

Lucene介绍:

       Lucene是一个高性能,可伸缩的全文检索工具包,可以使用他为你的应用程序添加索引和搜索能力。(注:它不是一个完整的搜索应用程序),Lucene目前是我们熟知的Apache里的一个开发项目,也是目前最为流行的基于Java开源全文检索工具包。

       官网:http://lucene.apache.org/,从官网上看可以发现其版本不止Java的还有.NET等等。

       目前已经有很多应用程序的搜索功能是基于Lucene的,例如我们用的Eclipse在第一次使用的时候,会有一个进度条,那就是创建索引的过程,方便Eclipse 的帮助系统的搜索功能。Lucene能够为文本类型的数据建立索引,所以你只要能把你要索引的数据格式转化为文本的,Lucene就能对你的文档进行索引和搜索。比如你要对一些HTML文档、PDF文档进行索引的话你就首先需要把HTML文档和PDF文档转换为文本格式的,然后将转换后的内容交给Lucene进行索引,然后再把创建好的索引文件保存到磁盘或内存中,最后根据用户输入的查询条件在索引文件上进行查询。

搜索应用程序和Lucene之间的关系:

 

 

在用之前,我们再来对一些Lucene里的名字进行解释一下

IndexWriter: Lucene中最重要的的类之一,它主要是用来将文档加入索引,同时控制索引过程中的一些参数使用。操作索引库   

    Analyzer:分析器,主要用于分析搜索引擎遇到的各种文本。常用的有StandardAnalyzer分析器,StopAnalyzer分析器,WhitespaceAnalyzer分析器等。   

    Directory:索引存放的位置; Lucene提供了两种索引存放的位置,一种是磁盘,一种是内存。一般情况将索引放在磁盘上;相应地lucene提供了FSDirectory和RAMDirectory两个类。   

    Document:文档;Document相当于一个要进行索引的单元,任何可以想要被索引的文件都必须转化为Document对象才能进行索引。   

    Field:字段。   

    IndexSearcher:是Lucene中最基本的检索工具,所有的检索都会用到IndexSearcher工具;   

    Query:查询,Lucene中支持模糊查询,语义查询,短语查询,组合查询等等,如有TermQuery,BooleanQuery,RangeQuery,WildcardQuery等一些类。   

    QueryParser: 是一个解析用户输入的工具,可以通过扫描用户输入的字符串,生成Query对象。   

    TopDocs:在搜索完成之后,需要把搜索结果返回并显示给用户,只有这样才算是完成搜索的目的。

 

 

 

Ok,废话就这么多,直接上代码。

 

FirstLucene

1、添加jar包

lucene-core-3.5.0.jar(核心)

lucene-analyzers-3.5.0.jar(分词器)

lucene-highlighter-3.5.0.jar(高亮器)

2、建立索引

3、 搜索

 

 

FirstLucene.java:

Java代码 复制代码 收藏代码
  1. package com.iflytek.lucene;   
  2.   
  3. import java.io.File;   
  4.   
  5. import org.apache.lucene.analysis.Analyzer;   
  6. import org.apache.lucene.analysis.standard.StandardAnalyzer;   
  7. import org.apache.lucene.document.Document;   
  8. import org.apache.lucene.index.IndexReader;   
  9. import org.apache.lucene.index.IndexWriter;   
  10. import org.apache.lucene.index.IndexWriterConfig;   
  11. import org.apache.lucene.queryParser.MultiFieldQueryParser;   
  12. import org.apache.lucene.queryParser.QueryParser;   
  13. import org.apache.lucene.search.Filter;   
  14. import org.apache.lucene.search.IndexSearcher;   
  15. import org.apache.lucene.search.Query;   
  16. import org.apache.lucene.search.ScoreDoc;   
  17. import org.apache.lucene.search.TopDocs;   
  18. import org.apache.lucene.store.Directory;   
  19. import org.apache.lucene.store.FSDirectory;   
  20. import org.apache.lucene.util.Version;   
  21.   
  22. /**  
  23.  * @author xudongwang 2012-2-2  
  24.  *   
  25.  *         Email:xdwangiflytek@gmail.com  
  26.  */  
  27. public class FirstLucene {   
  28.   
  29.     /**  
  30.      * 源文件路径  
  31.      */  
  32.     private String filePath01 = "F:\\Workspaces\\workspaceSE\\BlogDemo\\luceneDatasource\\HelloLucene01.txt";   
  33.     private String filePath02 = "F:\\Workspaces\\workspaceSE\\BlogDemo\\luceneDatasource\\HelloLucene02.txt";   
  34.     private String filePath03 = "F:\\Workspaces\\workspaceSE\\BlogDemo\\luceneDatasource\\HelloLucene03.txt";   
  35.   
  36.     /**  
  37.      * 索引路径  
  38.      */  
  39.     private String indexPath = "F:\\Workspaces\\workspaceSE\\BlogDemo\\luceneIndex";   
  40.   
  41.     /**  
  42.      * 分词器,这里我们使用默认的分词器,标准分析器(好几个,但对中文的支持都不好)  
  43.      */  
  44.     private Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_35);   
  45.   
  46.     /**  
  47.      * 创建索引  
  48.      *   
  49.      * @throws Exception  
  50.      */  
  51.     public void createIndex() throws Exception {   
  52.         Document document01 = File2Document.file2Document(filePath01);// 要进行索引的单元   
  53.         Document document02 = File2Document.file2Document(filePath02);   
  54.         Document document03 = File2Document.file2Document(filePath03);   
  55.   
  56.         // 将Document添加到索引库中   
  57.   
  58.         File indexFile = new File(indexPath);   
  59.         Directory directory = FSDirectory.open(indexFile);   
  60.         // IndexWriter是用来操作(增、删、改)索引库的   
  61.         // true,表示每次都创建新的,有了就删掉再创建   
  62.         IndexWriterConfig conf = new IndexWriterConfig(Version.LUCENE_35,   
  63.                 analyzer);   
  64.         IndexWriter indexWriter = new IndexWriter(directory, conf);   
  65.         indexWriter.addDocument(document01);   
  66.         indexWriter.addDocument(document02);   
  67.         indexWriter.addDocument(document03);   
  68.         indexWriter.close();// 涉及到资源的都需要释放   
  69.     }   
  70.   
  71.   
  72.     /**  
  73.      * 搜索  
  74.      *   
  75.      * @param queryStr  
  76.      *            搜索的关键词  
  77.      * @throws Exception  
  78.      */  
  79.     public void search(String queryStr) throws Exception {   
  80.   
  81.         // 1、把要搜索的文本解析为Query对象   
  82.         // 指定在哪些字段查询   
  83.         String[] fields = { "name", "content" };   
  84.         // QueryParser: 是一个解析用户输入的工具,可以通过扫描用户输入的字符串,生成Query对象。   
  85.         QueryParser queryParser = new MultiFieldQueryParser(Version.LUCENE_35,   
  86.                 fields, analyzer);   
  87.         // Query:查询,lucene中支持模糊查询,语义查询,短语查询,组合查询等等,如有TermQuery,BooleanQuery,RangeQuery,WildcardQuery等一些类。   
  88.         Query query = queryParser.parse(queryStr);   
  89.         // 2、进行查询   
  90.         File indexFile = new File(indexPath);   
  91.   
  92.         // IndexSearcher 是用来在索引库中进行查询的   
  93.         // IndexSearcher indexSearcher = new   
  94.         // IndexSearcher(FSDirectory.open(indexFile));   
  95.         Directory directory = FSDirectory.open(indexFile);   
  96.         IndexReader indexReader = IndexReader.open(directory);   
  97.         IndexSearcher indexSearcher = new IndexSearcher(indexReader);   
  98.         // Filter 过滤器,我们可以将查出来的结果进行过滤,可以屏蔽掉一些不想给用户看到的内容   
  99.         Filter filter = null;   
  100.         // 10000表示一次性在数据库中查询多少个文档   
  101.         // topDocs 类似集合   
  102.         TopDocs topDocs = indexSearcher.search(query, filter, 10000);   
  103.         System.out.println("总共有【" + topDocs.totalHits + "】条匹配的结果");// 注意这里的匹配结果是指文档的个数,而不是文档中包含搜索结果的个数   
  104.         // 3、打印结果   
  105.         for (ScoreDoc scoreDoc : topDocs.scoreDocs) {   
  106.             int docSn = scoreDoc.doc;// 文档内部编号   
  107.             Document document = indexSearcher.doc(docSn);// 根据文档编号取出相应的文档   
  108.             File2Document.printDocumentInfo(document);// 打印出文档信息   
  109.         }   
  110.     }   
  111.   
  112.     public static void main(String[] args) throws Exception {   
  113.         FirstLucene lucene = new FirstLucene();   
  114.         //lucene.createIndex();   
  115.         lucene.search("other");   
  116.         System.out.println("---------------------------");   
  117.         lucene.search("iteye");   
  118.         System.out.println("---------------------------");   
  119.         lucene.search("too");   
  120.         System.out.println("---------------------------");   
  121.     }   
  122.   
  123. }  
package com.iflytek.lucene;import java.io.File;import org.apache.lucene.analysis.Analyzer;import org.apache.lucene.analysis.standard.StandardAnalyzer;import org.apache.lucene.document.Document;import org.apache.lucene.index.IndexReader;import org.apache.lucene.index.IndexWriter;import org.apache.lucene.index.IndexWriterConfig;import org.apache.lucene.queryParser.MultiFieldQueryParser;import org.apache.lucene.queryParser.QueryParser;import org.apache.lucene.search.Filter;import org.apache.lucene.search.IndexSearcher;import org.apache.lucene.search.Query;import org.apache.lucene.search.ScoreDoc;import org.apache.lucene.search.TopDocs;import org.apache.lucene.store.Directory;import org.apache.lucene.store.FSDirectory;import org.apache.lucene.util.Version;/** * @author xudongwang 2012-2-2 *  *         Email:xdwangiflytek@gmail.com */public class FirstLucene {/** * 源文件路径 */private String filePath01 = "F:\\Workspaces\\workspaceSE\\BlogDemo\\luceneDatasource\\HelloLucene01.txt";private String filePath02 = "F:\\Workspaces\\workspaceSE\\BlogDemo\\luceneDatasource\\HelloLucene02.txt";private String filePath03 = "F:\\Workspaces\\workspaceSE\\BlogDemo\\luceneDatasource\\HelloLucene03.txt";/** * 索引路径 */private String indexPath = "F:\\Workspaces\\workspaceSE\\BlogDemo\\luceneIndex";/** * 分词器,这里我们使用默认的分词器,标准分析器(好几个,但对中文的支持都不好) */private Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_35);/** * 创建索引 *  * @throws Exception */public void createIndex() throws Exception {Document document01 = File2Document.file2Document(filePath01);// 要进行索引的单元Document document02 = File2Document.file2Document(filePath02);Document document03 = File2Document.file2Document(filePath03);// 将Document添加到索引库中File indexFile = new File(indexPath);Directory directory = FSDirectory.open(indexFile);// IndexWriter是用来操作(增、删、改)索引库的// true,表示每次都创建新的,有了就删掉再创建IndexWriterConfig conf = new IndexWriterConfig(Version.LUCENE_35,analyzer);IndexWriter indexWriter = new IndexWriter(directory, conf);indexWriter.addDocument(document01);indexWriter.addDocument(document02);indexWriter.addDocument(document03);indexWriter.close();// 涉及到资源的都需要释放}/** * 搜索 *  * @param queryStr *            搜索的关键词 * @throws Exception */public void search(String queryStr) throws Exception {// 1、把要搜索的文本解析为Query对象// 指定在哪些字段查询String[] fields = { "name", "content" };// QueryParser: 是一个解析用户输入的工具,可以通过扫描用户输入的字符串,生成Query对象。QueryParser queryParser = new MultiFieldQueryParser(Version.LUCENE_35,fields, analyzer);// Query:查询,lucene中支持模糊查询,语义查询,短语查询,组合查询等等,如有TermQuery,BooleanQuery,RangeQuery,WildcardQuery等一些类。Query query = queryParser.parse(queryStr);// 2、进行查询File indexFile = new File(indexPath);// IndexSearcher 是用来在索引库中进行查询的// IndexSearcher indexSearcher = new// IndexSearcher(FSDirectory.open(indexFile));Directory directory = FSDirectory.open(indexFile);IndexReader indexReader = IndexReader.open(directory);IndexSearcher indexSearcher = new IndexSearcher(indexReader);// Filter 过滤器,我们可以将查出来的结果进行过滤,可以屏蔽掉一些不想给用户看到的内容Filter filter = null;// 10000表示一次性在数据库中查询多少个文档// topDocs 类似集合TopDocs topDocs = indexSearcher.search(query, filter, 10000);System.out.println("总共有【" + topDocs.totalHits + "】条匹配的结果");// 注意这里的匹配结果是指文档的个数,而不是文档中包含搜索结果的个数// 3、打印结果for (ScoreDoc scoreDoc : topDocs.scoreDocs) {int docSn = scoreDoc.doc;// 文档内部编号Document document = indexSearcher.doc(docSn);// 根据文档编号取出相应的文档File2Document.printDocumentInfo(document);// 打印出文档信息}}public static void main(String[] args) throws Exception {FirstLucene lucene = new FirstLucene();//lucene.createIndex();lucene.search("other");System.out.println("---------------------------");lucene.search("iteye");System.out.println("---------------------------");lucene.search("too");System.out.println("---------------------------");}}

 

 

 File2Document.java:

Java代码 复制代码 收藏代码
  1. package com.iflytek.lucene;   
  2.   
  3. import java.io.BufferedReader;   
  4. import java.io.File;   
  5. import java.io.FileInputStream;   
  6. import java.io.FileNotFoundException;   
  7. import java.io.IOException;   
  8. import java.io.InputStreamReader;   
  9.   
  10. import org.apache.lucene.document.Document;   
  11. import org.apache.lucene.document.Field;   
  12. import org.apache.lucene.document.Field.Index;   
  13. import org.apache.lucene.document.Field.Store;   
  14.   
  15. /**  
  16.  * @author xudongwang 2012-2-2  
  17.  *   
  18.  *         Email:xdwangiflytek@gmail.com  
  19.  */  
  20. public class File2Document {   
  21.     /**  
  22.      * File--->Document  
  23.      *   
  24.      * @param filePath  
  25.      *            File路径  
  26.      *   
  27.      * @return Document对象  
  28.      */  
  29.     public static Document file2Document(String filePath) {   
  30.         // 文件要存放:name,content,size,path   
  31.         File file = new File(filePath);   
  32.   
  33.         Document document = new Document();   
  34.         // Store.YES 是否存储 yes no compress(压缩之后再存)   
  35.         // Index 是否进行索引 Index.ANALYZED 分词后进行索引,NOT_ANALYZED 不索引,NOT_ANALYZED   
  36.         // 不分词直接索引   
  37.         document.add(new Field("name", file.getName(), Store.YES,   
  38.                 Index.ANALYZED));   
  39.         document.add(new Field("content", readFileContent(file), Store.YES,   
  40.                 Index.ANALYZED));   
  41.         document.add(new Field("size", String.valueOf(file.length()),   
  42.                 Store.YES, Index.NOT_ANALYZED));// 不分词,但是有时需要索引,文件大小(int)转换成String   
  43.         document.add(new Field("path", file.getAbsolutePath(), Store.YES,   
  44.                 Index.NOT_ANALYZED));// 不需要根据文件的路径来查询   
  45.         return document;   
  46.     }   
  47.   
  48.     /**  
  49.      * 读取文件内容  
  50.      *   
  51.      * @param file  
  52.      *            File对象  
  53.      * @return File的内容  
  54.      */  
  55.     private static String readFileContent(File file) {   
  56.         try {   
  57.             BufferedReader reader = new BufferedReader(new InputStreamReader(   
  58.                     new FileInputStream(file)));   
  59.             StringBuffer content = new StringBuffer();   
  60.             try {   
  61.                 for (String line = null; (line = reader.readLine()) != null;) {   
  62.                     content.append(line).append("\n");   
  63.                 }   
  64.             } catch (IOException e) {   
  65.   
  66.                 e.printStackTrace();   
  67.             }   
  68.             return content.toString();   
  69.         } catch (FileNotFoundException e) {   
  70.   
  71.             e.printStackTrace();   
  72.         }   
  73.         return null;   
  74.     }   
  75.   
  76.     /**  
  77.      * <pre>  
  78.      * 获取name属性值的两种方法    
  79.      * 1.Filed field = document.getFiled("name");    
  80.      *         field.stringValue();    
  81.      * 2.document.get("name");  
  82.      * </pre>  
  83.      *   
  84.      * @param document  
  85.      */  
  86.     public static void printDocumentInfo(Document document) {   
  87.         // TODO Auto-generated method stub   
  88.         System.out.println("name -->" + document.get("name"));   
  89.         System.out.println("content -->" + document.get("content"));   
  90.         System.out.println("path -->" + document.get("path"));   
  91.         System.out.println("size -->" + document.get("size"));   
  92.     }   
  93. }  
package com.iflytek.lucene;import java.io.BufferedReader;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.io.InputStreamReader;import org.apache.lucene.document.Document;import org.apache.lucene.document.Field;import org.apache.lucene.document.Field.Index;import org.apache.lucene.document.Field.Store;/** * @author xudongwang 2012-2-2 *  *         Email:xdwangiflytek@gmail.com */public class File2Document {/** * File--->Document *  * @param filePath *            File路径 *  * @return Document对象 */public static Document file2Document(String filePath) {// 文件要存放:name,content,size,pathFile file = new File(filePath);Document document = new Document();// Store.YES 是否存储 yes no compress(压缩之后再存)// Index 是否进行索引 Index.ANALYZED 分词后进行索引,NOT_ANALYZED 不索引,NOT_ANALYZED// 不分词直接索引document.add(new Field("name", file.getName(), Store.YES,Index.ANALYZED));document.add(new Field("content", readFileContent(file), Store.YES,Index.ANALYZED));document.add(new Field("size", String.valueOf(file.length()),Store.YES, Index.NOT_ANALYZED));// 不分词,但是有时需要索引,文件大小(int)转换成Stringdocument.add(new Field("path", file.getAbsolutePath(), Store.YES,Index.NOT_ANALYZED));// 不需要根据文件的路径来查询return document;}/** * 读取文件内容 *  * @param file *            File对象 * @return File的内容 */private static String readFileContent(File file) {try {BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));StringBuffer content = new StringBuffer();try {for (String line = null; (line = reader.readLine()) != null;) {content.append(line).append("\n");}} catch (IOException e) {e.printStackTrace();}return content.toString();} catch (FileNotFoundException e) {e.printStackTrace();}return null;}/** * <pre> * 获取name属性值的两种方法   * 1.Filed field = document.getFiled("name");   *         field.stringValue();   * 2.document.get("name"); * </pre> *  * @param document */public static void printDocumentInfo(Document document) {// TODO Auto-generated method stubSystem.out.println("name -->" + document.get("name"));System.out.println("content -->" + document.get("content"));System.out.println("path -->" + document.get("path"));System.out.println("size -->" + document.get("size"));}}

  

 

HelloLucene01.txt:

Hello, my name is wang xudong, I in iteye blog address is xdwangiflytek.iteye.com.

 

HelloLucene02.txt:

Hello, my name is wang xudong, I in iteye blog address is xdwangiflytek.iteye.com too.

 

HelloLucene03.txt:

iteye too other.

 

 

创建的目录结构为:

 

 

 

运行结果:

 

 

 

 

原创粉丝点击