最近在公司实习,学习了个吧星期的lucene,现在把自己学习的一点点体会和大家分享哈!
学习lucene的几个主要类:
1,Query类:这是一个抽象类,用于将用户输入的查询字符串封装成Lucene能够识别的Query,它具有TermQuery, BooleanQuery, PrefixQuery等多种实现。
2,Term类:用于描述搜索的基本单位,其构造函数是Term(“fieldName”,”queryWord”),其中第一个参数代表要在文档的哪一个Field上进行搜索,第二个参数代表要搜索的关键词。
3,TermQuery类:TermQuery是抽象类Query的一个具体实现,也是Lucene支持的最为基本的一个查询类。TermQuery的构造函数是TermQuery(new Term(“fieldName”,”queryWord”)),唯一的参数是一个Term对象。
4,IndexSearcher类:用于在建立好的索引上进行搜索的句柄类,其打开索引方式被设置为只读,因此允许多个IndexSearcher实例操作同一个索引。
5,Hits类:搜索结果类。
当然我们先来个Hello World!看看lucene的效果!!
1 package cn.itcast.lucene.helloworld; 2 3 import jeasy.analysis.MMAnalyzer; 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.IndexWriter; 9 import org.apache.lucene.index.IndexWriter.MaxFieldLength; 10 import org.apache.lucene.queryParser.MultiFieldQueryParser; 11 import org.apache.lucene.queryParser.QueryParser; 12 import org.apache.lucene.search.Filter; 13 import org.apache.lucene.search.IndexSearcher; 14 import org.apache.lucene.search.Query; 15 import org.apache.lucene.search.ScoreDoc; 16 import org.apache.lucene.search.TopDocs; 17 import org.junit.Test; 18 19 import cn.itcast.lucene.utils.File2DocumentUtils; 20 21 public class HelloWorld { 22 23 String filePath = "D:\\Users\\Dingwei\\workspace_4_2\\luceue\\luceneDatasource\\config"; 24 25 String indexPath = "D:\\Users\\Dingwei\\workspace_4_2\\luceue\\luceneIndex"; 26 27 Analyzer analyzer = new MMAnalyzer(); 28 29 /** 30 * 创建索引 31 * 32 * IndexWriter 是用来操作(增、删、改)索引库的 33 */ 34 @Test 35 public void createIndex() throws Exception { 36 // file --> doc 37 Document doc = File2DocumentUtils.file2Document(filePath); //将文件解析为document 38 39 // 建立索引 40 IndexWriter indexWriter = new IndexWriter(indexPath, analyzer, true, 41 MaxFieldLength.LIMITED); // true 每次创建新的索引库(旧的删除了再重新创建)MaxFieldLength.LIMITED最大分词的限定,默认一万 42 indexWriter.addDocument(doc); // 增加索引库 43 indexWriter.optimize(); //优化文件(合并小的文件成大文件) 44 indexWriter.close(); // 释放资源 45 } 46 47 /** 48 * 搜索 49 * 50 * IndexSearcher 是用来在索引库中进行查询的 51 */ 52 @Test 53 public void search() throws Exception { 54 // String queryString = "document"; 55 String queryString = "root";//查询字段 56 57 // 1,把要搜索的文本document解析为 Query 58 String[] fields = { "name", "content" };//搜索的字段(内容) 59 QueryParser queryParser = new MultiFieldQueryParser(fields, analyzer); //文本解析为query对象 60 Query query = queryParser.parse(queryString);//查询内容 61 62 // 2,进行查询 63 IndexSearcher indexSearcher = new IndexSearcher(indexPath);//搜索索引库 64 Filter filter = null; //过滤器 65 TopDocs topDocs = indexSearcher.search(query, filter, 10000);//topDocs查询结果 66 System.out.println("总共有【" + topDocs.totalHits + "】条匹配结果"); 67 68 // 3,打印结果(支持分页) 69 for (ScoreDoc scoreDoc : topDocs.scoreDocs) { 70 int docSn = scoreDoc.doc; // 文档内部编号 71 Document doc = indexSearcher.doc(docSn); // 根据编号取出相应的文档 72 File2DocumentUtils.printDocumentInfo(doc); // 打印出文档信息 73 } 74 } 75 }
1 import java.io.BufferedReader; 2 import java.io.File; 3 import java.io.FileInputStream; 4 import java.io.InputStreamReader; 5 6 import org.apache.lucene.document.Document; 7 import org.apache.lucene.document.Field; 8 import org.apache.lucene.document.NumberTools; 9 import org.apache.lucene.document.Field.Index; 10 import org.apache.lucene.document.Field.Store; 11 12 public class File2DocumentUtils { 13 14 // 文件:name, content, size, path (文件到document的转换) 15 public static Document file2Document(String path) { 16 File file = new File(path); 17 18 Document doc = new Document();//Document是field的集合,很多键值对 19 doc.add(new Field("name", file.getName(), Store.YES, Index.ANALYZED));//Index.ANALYZED分词后进行索引 20 doc.add(new Field("content", readFileContent(file), Store.YES, Index.ANALYZED)); 21 doc.add(new Field("size", NumberTools.longToString(file.length()), Store.YES,Index.NOT_ANALYZED));//Index.NOT_ANALYZED不分词直接索引 22 doc.add(new Field("path", file.getAbsolutePath(), Store.YES, Index.NOT_ANALYZED)); 23 return doc; 24 } 25 26 // public static void document2File(Document doc ){ 27 // 28 // } 29 30 /** 31 * 读取文件内容 32 */ 33 public static String readFileContent(File file) { 34 try { 35 BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file))); 36 StringBuffer content = new StringBuffer(); 37 38 for (String line = null; (line = reader.readLine()) != null;) { 39 content.append(line).append("\n"); 40 } 41 42 return content.toString(); 43 } catch (Exception e) { 44 throw new RuntimeException(e); 45 } 46 } 47 48 /** 49 * <pre> 50 * 获取 name 属性的值的两种方法: 51 * 1,Field f = doc.getField("name"); 52 * f.stringValue(); 53 * 2,doc.get("name"); 54 * </pre> 55 * 56 * @param doc 57 */ 58 public static void printDocumentInfo(Document doc) { 59 // Field f = doc.getField("name"); 60 // f.stringValue(); 61 System.out.println("------------------------------"); 62 System.out.println("name = " + doc.get("name")); 63 System.out.println("content = " + doc.get("content")); 64 System.out.println("size = " + NumberTools.stringToLong(doc.get("size"))); 65 System.out.println("path = " + doc.get("path")); 66 } 67 68 }
其实很简单的,只要记得lucene的原理:首先从两方面来说,1.用户输入自己查询的关键词(句),会分词,来匹配索引库(directory)里面的索引(index);2.系统首先会会把file解析成document,然后indexwrite会来创建索引(有点值得注意的是如果你的查询或者关键词句需要分词的话用到的分词器analyzer一定要和把file转换成document的分词器是一个);
关于索引结构:
关于中文分词: