一、lucene2.4的创建和查询及其分词显示
2013-04-12 11:13
369 查看
1、工程目录
2、lucene的创建搜索过程
3、建立索引的示意图
4、硬盘和内存中创建索引示意图
5、lucene的创建及其搜索的代码
6、lucene创建索引的两种方式
7、中英文分词器的分词结果显示及测试
8、lucene的工具方法
工程代码:http://download.csdn.net/detail/wxwzy738/5248905
2、lucene的创建搜索过程
3、建立索引的示意图
4、硬盘和内存中创建索引示意图
5、lucene的创建及其搜索的代码
package cn.hj.lucene.helloworld; import jeasy.analysis.MMAnalyzer; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.document.Document; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriter.MaxFieldLength; 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.search.highlight.Formatter; import org.apache.lucene.search.highlight.Fragmenter; import org.apache.lucene.search.highlight.Highlighter; import org.apache.lucene.search.highlight.QueryScorer; import org.apache.lucene.search.highlight.Scorer; import org.apache.lucene.search.highlight.SimpleFragmenter; import org.apache.lucene.search.highlight.SimpleHTMLFormatter; import org.junit.Test; import cn.hj.lucene.utils.File2DocumentUtils; public class HelloWorld { //资源文件的路径,也就是要进行索引的文件 // String filePath = "D:\\Workspaces\\lucenedemo\\luceneDatasource\\IndexWriter addDocument's a javadoc .txt"; String filePath = "D:\\Workspaces\\lucenedemo\\luceneDatasource\\小笑话_总统的房间 Room.txt"; //索引文件所存放的路径 String indexPath ="D:\\Workspaces\\lucenedemo\\luceneIndex"; //标准分词器 // Analyzer analyzer = new StandardAnalyzer(); Analyzer analyzer = new MMAnalyzer(); /** * 创建索引 * IndexWriter是用来操作(增、删、改)索引库的 */ @Test public void createIndex() throws Exception{ Document doc = File2DocumentUtils.file2Document(filePath); //可以对某些文档设置权重,数字越大权重越高 doc.setBoost(3.0f); //第三个参数设置为true的话表示每次执行都会创建目录和删除之前文件重新创建 // 设置为false如果目录不存在会生成目录,但是如果是第一次生成文件的话,会报错, //如果原来的索引存在则不会保存,原来的索引文件也不会删除,会再生成一份索引和原来合并 //第四个参数表示每个字段中有多少个索引词来进行限定的,防止内存溢出等, // 比如有一个字段有几十万字,那索引出来的词便会很多 //MaxFieldLength.LIMITED表示为一万 MaxFieldLength.UNLIMITED表示为无限大 IndexWriter indexWriter = new IndexWriter(indexPath,analyzer,false,MaxFieldLength.LIMITED); indexWriter.addDocument(doc); indexWriter.close(); System.out.println("create ok..."); } /** * 搜索 * IndexSearcher是用来在索引库中进行查询的 * @throws Exception */ @Test public void search() throws Exception{ String queryString = "document";//要查询的关键字 //1、把要搜索的文本解析为Query String[] fields = {"name","content"};//要在哪些字段上进行查询 //QueryParser为解析器 //MultiFieldQueryParser为多个字段的解析器,参数为字段数组和分词器 QueryParser queryParser = new MultiFieldQueryParser(fields, analyzer); //分析器经过解析之后得到一个查询器 Query query = queryParser.parse(queryString); //2、进行查询 IndexSearcher indexSearcher = new IndexSearcher(indexPath); //过滤器是对查询后的结果进行过滤,比如包含哪些词,文件大小超过多少等 Filter filter = null; //过滤器为null为表示没有,不进行过滤 //第三个参数表示一次查询多少个结果,默认是50,一般1000~10000即可 //如果设置为1000,但是要取2000条,那么会分两次查询 //得到搜索结果的集合存放入TopDocs中 TopDocs topDocs = indexSearcher.search(query, filter, 1000); int totalHits = topDocs.totalHits; System.out.println("共有【"+totalHits+"】条匹配结果."); //3、打印结果 //得到的结果并不是真正的结果,只是文档编号的结果,这样数据量少,速度快 ScoreDoc[] scoreDocs = topDocs.scoreDocs; for(ScoreDoc scoreDoc : scoreDocs){ int docNum = scoreDoc.doc;//得到文档编号 Document doc = indexSearcher.doc(docNum);//通过文档编号得到文档 //在得到文档的时候对关键字来进行高亮显示 Highlighter highlighter = getHighlighter(query); String hc = highlighter.getBestFragment(analyzer, "content", doc.get("content")); //返回高亮后的结果,如果当前属性值中没有出现关键字,则返回null if(hc != null){ //对原来的全部内容进行清除,把摘要信息进行赋值,比如在列表中需要只显示摘要不显示全部信息 doc.getField("content").setValue(hc); } File2DocumentUtils.printDocument(doc); } } /** * 准备高亮器 * @param query */ public Highlighter getHighlighter(Query query){ //指定要显示的是什么样的格式,这里是直接加红 Formatter formatter = new SimpleHTMLFormatter("<font color='red'>", "</font>"); Scorer scorer = new QueryScorer(query); Highlighter highlighter = new Highlighter(formatter, scorer); //取关键字出现最频繁的那一段文本附近的指定个数的字符作为摘要 //截取摘要信息50个字符 Fragmenter fragmenter = new SimpleFragmenter(50); highlighter.setTextFragmenter(fragmenter); return highlighter; } }
6、lucene创建索引的两种方式
package cn.hj.lucene.director; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriter.MaxFieldLength; import org.apache.lucene.store.Directory; import org.apache.lucene.store.FSDirectory; import org.apache.lucene.store.RAMDirectory; import org.junit.Test; import cn.hj.lucene.utils.File2DocumentUtils; /** * 创建索引的两种方式 * 1、创建的索引存放在硬盘中 * 2、创建的索引放入内存当中,程序结束索引也消失 */ public class DirectorTest { //资源文件的路径,也就是要进行索引的文件 String filePath = "D:\\Workspaces\\lucenedemo\\luceneDatasource\\IndexWriter addDocument's a javadoc .txt"; //索引文件所存放的路径 String indexPath ="D:\\Workspaces\\lucenedemo\\luceneIndex"; //标准分词器 Analyzer analyzer = new StandardAnalyzer(); @Test public void test1() throws Exception{ // Directory directory = FSDirectory.getDirectory(indexPath);//硬盘索引 Directory directory = new RAMDirectory(indexPath);//内存索引 Document doc = File2DocumentUtils.file2Document(filePath); //若第一个参数传入文件路径,默认内部会封装成Directory对象 //create属性不填的话默认第一次会创建,接着的话会重新生成一份和原来的索引合并 IndexWriter indexWriter = new IndexWriter(directory, analyzer,MaxFieldLength.LIMITED); indexWriter.addDocument(doc); indexWriter.close(); } /** * 1、把索引文件建在硬盘中存放,这样web应用关闭不会丢失 * 2、可以在启动web应用的时候把硬盘的索引通过RAMDirectory写入内存中进行操作 * 3、web应用不用或退出的时候把操作的数据保存入硬盘中,从而不让数据丢失 * 一个实际应用: * 因为在网站运营的时候需要经常创建索引,讲究及时性,那么可以先把索引放入内存 * 中创建,最后把内存中的索引写入硬盘,这样总体速度变快 */ public void fsDir2ramDir() throws Exception{ Directory fsDir = FSDirectory.getDirectory(indexPath); //1、启动时读取 Directory ramDir = new RAMDirectory(fsDir);//直接把硬盘中的数据读入内存 //运行程序时操作ramDir IndexWriter ramIndexWriter = new IndexWriter(ramDir, analyzer, MaxFieldLength.LIMITED); //往内存索引中添加Document Document doc = File2DocumentUtils.file2Document(filePath); ramIndexWriter.addDocument(doc); ramIndexWriter.close();//如果不关闭的话数据会在缓存中 //2、退出时保存 //如果这里第三个参数是否重新创建 不写成true的话,那么会有问题 //假设刚开始硬盘中有2个document文件,这2个文档写入内存后,又在内存中添加一个文档,内存共3个文档 //这三个文档又重新写入到硬盘,那么硬盘就有5个文档了,其中两个文档是重复的,所以硬盘的索引要重新创建 IndexWriter fsIndexWriter = new IndexWriter(fsDir,analyzer,true,MaxFieldLength.LIMITED); //把内存的索引写入硬盘,同时NoOptimize不做优化 fsIndexWriter.addIndexesNoOptimize(new Directory[]{ramDir}); fsIndexWriter.close(); } /** * 当文件很多的时候,那么io操作就慢,那么需要合并和优化 */ @Test public void optimize() throws Exception{ Directory fsDir = FSDirectory.getDirectory(indexPath); IndexWriter fsIndexWriter = new IndexWriter(fsDir,analyzer,MaxFieldLength.LIMITED); // fsIndexWriter.flush();//过时了,用commit()代替 fsIndexWriter.commit();//把索引刷出缓存 fsIndexWriter.optimize();//进行优化 fsIndexWriter.close(); } }
7、中英文分词器的分词结果显示及测试
package cn.hj.lucene.analyzer; import java.io.StringReader; import jeasy.analysis.MMAnalyzer; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.SimpleAnalyzer; import org.apache.lucene.analysis.Token; import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.analysis.cjk.CJKAnalyzer; import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.junit.Test; /** * 中英文分词器的分词结果显示及测试 */ public class AnalyzerTest { String enText = "IndexWriter addDocument's a javadoc.txt"; String cnText = "我们是中国人"; Analyzer en1 = new StandardAnalyzer(); /* ------------>分词器:class org.apache.lucene.analysis.standard.StandardAnalyzer (indexwriter,0,11,type=<ALPHANUM>) (adddocument,12,25,type=<APOSTROPHE>) (javadoc.txt,28,39,type=<HOST>) */ Analyzer en2 = new SimpleAnalyzer(); /* ------------>分词器:class org.apache.lucene.analysis.SimpleAnalyzer (indexwriter,0,11) (adddocument,12,23) (s,24,25) (a,26,27) (javadoc,28,35) (txt,36,39) */ Analyzer cn1 = new StandardAnalyzer();//单字分词 /* ------------>分词器:class org.apache.lucene.analysis.standard.StandardAnalyzer (我,0,1,type=<CJ>) (们,1,2,type=<CJ>) (是,2,3,type=<CJ>) (中,3,4,type=<CJ>) (国,4,5,type=<CJ>) (人,5,6,type=<CJ>) */ Analyzer cn2 = new CJKAnalyzer();//二分法分词 /* ------------>分词器:class org.apache.lucene.analysis.cjk.CJKAnalyzer (我们,0,2,type=double) (们是,1,3,type=double) (是中,2,4,type=double) (中国,3,5,type=double) (国人,4,6,type=double) */ Analyzer cn3 = new MMAnalyzer();//极易分词,按词库来分词,还有庖丁分词也类似 /* ------------>分词器:class jeasy.analysis.MMAnalyzer (我们,0,2) (中国人,3,6) */ //最好的还是按语义分词,据说中科院已经研究出 @Test public void test() throws Exception{ analyzer(cn3, cnText); } /** * 把一段文本按照分词器进行分词得到分词后的集合进行展示 * @param analyzer * @param text * @throws Exception */ public void analyzer(Analyzer analyzer, String text)throws Exception{ System.out.println("------------>分词器:"+analyzer.getClass()); TokenStream tokenStream = analyzer.tokenStream("content", new StringReader(text)); for(Token token = new Token();(token = tokenStream.next(token)) != null;){ System.out.println(token); } } }
8、lucene的工具方法
package cn.hj.lucene.utils; import java.io.File; import java.io.IOException; import org.apache.commons.io.FileUtils; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.document.NumberTools; import org.apache.lucene.document.Field.Index; import org.apache.lucene.document.Field.Store; public class File2DocumentUtils { /** * 把文件内容转化为Document * @param path * @return */ public static Document file2Document(String path){ File file = new File(path); Document doc = new Document(); doc.add(new Field("name",file.getName(),Store.YES,Index.ANALYZED)); try { doc.add(new Field("content",FileUtils.readFileToString(file),Store.YES,Index.ANALYZED)); } catch (IOException e) {e.printStackTrace();} doc.add(new Field("size",String.valueOf(path.length()),Store.YES,Index.NOT_ANALYZED)); doc.add(new Field("path",path,Store.YES,Index.NO)); return doc; } /** * 打印搜索结果信息 */ public static void printDocument(Document doc){ //第一种方式的获取值 // Field field = doc.getField("name"); // String name = field.stringValue(); //第二种方式的获取值 System.out.println("----------------------------------"); System.out.println("name = "+doc.get("name")); System.out.println("content = "+doc.get("content")); // System.out.println("size = "+doc.get("size")); System.out.println("size = "+NumberTools.stringToLong(doc.get("size"))); System.out.println("path = "+doc.get("path")); } }
工程代码:http://download.csdn.net/detail/wxwzy738/5248905
相关文章推荐
- Lucene 3.6.1:中文分词、创建索引库、排序、多字段分页查询以及高亮显示
- lucene之中文分词及其高亮显示(五)
- Lucene学习一:入门级Demo,创建索引和查询高亮显示
- 二、lucene2.4的增删改查及其查询语法
- lucene之中文分词及其高亮显示
- Lucene开发实例教程:Lucene中文分词、分页查询、高亮显示
- Lucene高亮显示及中文分词
- Lucene基础(三)-- 中文分词及高亮显示
- Oracle基础学习二:表的创建 数据的操作 在VS程序中的查询显示
- Linux 文件的创建、查询显示和链接
- Lucene中文分词的highlight显示
- [转]Lucene 中文分词的 highlight 显示
- LuceneSearch 现在要对查询结果进行排序的显示。
- oracle 创建自增列及其oracle表的字段的子节点的查询
- lucene2.4集成几种中文分词实例代码
- lucene(五) 中文分词和高亮显示
- Session机制、持久化、session="false"属性不创建session、显示创建session及其销毁
- lucene中处理将查询结果中的关键字高亮显示
- lucene 中文分词和结果高亮显示
- Lucene学习笔记(1)-索引创建和简单的查询