lunece全文检索的入门与简单优化
2016-12-15 项目中需要加载下面几个工具包1 package com.cn.shupu.util; import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Date;
import java.util.List; import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.LogByteSizeMergePolicy;
import org.apache.lucene.index.LogMergePolicy;
import org.apache.lucene.index.IndexWriterConfig.OpenMode;
import org.apache.lucene.queryparser.classic.QueryParser;
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.Fragmenter;
import org.apache.lucene.search.highlight.Highlighter;
import org.apache.lucene.search.highlight.InvalidTokenOffsetsException;
import org.apache.lucene.search.highlight.QueryScorer;
import org.apache.lucene.search.highlight.SimpleFragmenter;
import org.apache.lucene.search.highlight.SimpleHTMLFormatter;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.store.RAMDirectory; public class LuneceTest { // 用来文件
public static List<File> files = new ArrayList<File>(); // 保存索引文件
public static List<File> saveFile(File sourceFile) { File[] fs = sourceFile.listFiles(); for (int i = 0; i < fs.length; i++) { if (fs[i].isFile()) { files.add(fs[i]);
} else { saveFile(fs[i]);
} } return files; } // 获取文件中的内容
public static String saveContent(File file) { String content = ""; try { // 创建一个字符输入流
FileInputStream fis = new FileInputStream(file); // 创建一个桥梁让字节流转化为字符流
InputStreamReader isr = new InputStreamReader(fis, "GBK");
// 创建一个字符流缓存区
BufferedReader br = new BufferedReader(isr); String s = null; while ((s = br.readLine()) != null) { // 把内容拼接起来
content = content + "\n" + s; } // 关闭流
br.close();
isr.close();
fis.close(); } catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} return content; } // 创建索引
public static void createIndex(String sourcePath, String indexPath) { // 要索引的文件路径
File sourceFile = new File(sourcePath); // 获取索引文件的文件
List<File> fs = saveFile(sourceFile); Date date1 = new Date(); // 对文件进行索引
// 索引文件存放路径
Directory dir; try { // 索引优化
RAMDirectory rd = new RAMDirectory();
// 这里的路径为保存索引的路径
dir = FSDirectory.open(Paths.get(indexPath));
// 创建一个分词器
SmartChineseAnalyzer analyzer = new SmartChineseAnalyzer();
IndexWriterConfig iwc = new IndexWriterConfig(analyzer);// 初始化索引器
// 创建索引器
// IndexWriter writer = new IndexWriter(dir, iwc);//
// 第一个参数为索引存放的位置,第二参数为初始化参数 IndexWriter writer = new IndexWriter(rd, iwc); IndexWriterConfig iwc2 = new IndexWriterConfig(analyzer);// 初始化索引器
iwc2.setOpenMode(OpenMode.CREATE_OR_APPEND);
iwc2.setMaxBufferedDocs(256);
iwc2.setRAMBufferSizeMB(100); // SetMergeFactor是控制segment合并频率的,其决定了一个索引块中包括多少个文档,当硬盘上的索引块达到多少时,
// 将它们合并成一个较大的索引块。当MergeFactor值较大时,生成索引的速度较快。MergeFactor的默认值是10,建议在建立索引前将其设置的大一些。
LogMergePolicy mergePolicy = new LogByteSizeMergePolicy();
mergePolicy.setMergeFactor(100);
iwc2.setMergePolicy(mergePolicy); // 把缓存在 RAMDirectory 中的所有数据写入 FSDirectory
IndexWriter is = new IndexWriter(dir, iwc2); for (int i = 0; i < fs.size(); i++) { String content = ""; // 只对.txt文件进行索引
// 获取文件类型
int a = fs.get(i).getName().lastIndexOf("."); String fileType = fs.get(i).getName().substring(a + 1); if ("txt".equals(fileType)) { content = saveContent(fs.get(i)); // System.out.println(content); // System.out.println(fs.get(i).getName());
Document doc = new Document(); // doc.add(new TextField("filename", fs.get(i).getName(),
// Store.YES));
doc.add(new TextField("path", fs.get(i).getAbsolutePath(), Store.YES));
doc.add(new TextField("content", content, Store.YES));
writer.addDocument(doc); } }
writer.commit();
writer.close();
//
is.addIndexes(new Directory[] { rd });
is.forceMerge(5);
is.forceMerge(100);
is.maybeMerge();
is.close(); } catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} Date date2 = new Date();
System.out.println("创建索引-----耗时:" + (date2.getTime() - date1.getTime()) + "ms\n"); } // 搜索文件
public static void search(String indexPath, String keyword) { Date date1 = new Date(); Directory dir; try { dir = FSDirectory.open(Paths.get(indexPath)); // 创建分词器
SmartChineseAnalyzer analyzer = new SmartChineseAnalyzer();
// 打开索引的存放位置
DirectoryReader dr = DirectoryReader.open(dir); // 创建检索器
IndexSearcher is = new IndexSearcher(dr); QueryParser parser = new QueryParser("content", analyzer);// 第一个参数为要搜索的字段名,第二额分词器 Query query = parser.parse(keyword); TopDocs results = is.search(query, 100); ScoreDoc[] hits = results.scoreDocs;// 检索得到结果集 for (int i = 0; i < hits.length; i++) { // 获取一个条记录
Document doc = is.doc(hits[i].doc); // 获取路径
String path = doc.get("path");
// 获取 内容
String content = doc.get("content");
String filename = doc.get("filename"); String s = hight(query, analyzer, "content", content, 200); System.out.println("____________________________"); // System.out.println("文件名--------" + filename);
//
// sSystem.out.println("内容:---------" + s); System.out.println("文件路径-----" + path); System.out.println("____________________________"); } dr.close();
dir.close(); } catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} Date date2 = new Date();
System.out.println("查看索引-----耗时:" + (date2.getTime() - date1.getTime()) + "ms\n"); } /**
* 获取高亮显示结果的html代码
*
* @param query
* 查询
* @param analyzer
* 分词器
* @param fieldName
* 域名
* @param fieldContent
* 域内容
* @param fragmentSize
* 结果的长度(不含html标签长度)
* @return 结果(一段html代码)
* @throws IOException
* @throws InvalidTokenOffsetsException
*/
public static String hight(Query query, Analyzer analyzer, String filedname, String filedContent, int fragmentSize)
throws IOException, InvalidTokenOffsetsException { // 创建一个高亮器
Highlighter hightlighter = new Highlighter(new SimpleHTMLFormatter("<font color='red'>", "</font>"),
new QueryScorer(query)); // 查询结果的内容长度设定
Fragmenter framenter = new SimpleFragmenter(fragmentSize); hightlighter.setTextFragmenter(framenter); return hightlighter.getBestFragment(analyzer, filedname, filedContent);
} public static void main(String[] args) { createIndex("D:\\图书文件", "c:\\expal"); search("c:\\expal", "炎");// 22385ms 10380ms 35221ms 96583ms 66798ms
// 169438ms 179478ms }
lunece全文检索的入门与简单优化的更多相关文章
- Elasticsearch全文检索工具入门
Elasticsearch全文检索工具入门: 1.下载对应系统版本的文件 elasticsearch-2.4.0.zip 1.1运行elasticsearch-2.4.0\elasticsearch- ...
- 2,turicreate入门 - 一个简单的回归模型
turicreate入门系列文章目录 1,turicreate入门 - jupyter & turicreate安装 2,turicreate入门 - 一个简单的回归模型 3,turicrea ...
- 踢爆IT劣书出版黑幕——由清华大学出版社之《C语言入门很简单》想到的(1)
1.前言与作者 首先声明,我是由于非常偶然的机会获得<C语言入门很简单>这本书的,绝对不是买的.买这种书实在丢不起那人. 去年这书刚出版时,在CU论坛举行试读推广,我当时随口说了几句(没说 ...
- 一次千万级别的SQL查询简单优化体验
背景:从两张有关联的表查询数据,A表数据量1400万,B表数据量8000万.A与B通过ID逻辑关联,没有实际的外键.B表是后来扩展出来的. 问题:根据某个ID查询时超时,运行时跑不出结果. 原因:使用 ...
- [电子书] 《Android编程入门很简单》
<Android编程入门很简单>是一本与众不同的Android学习读物,是一本化繁为简,把抽象问题具体化,把复杂问题简单化的书.本书避免出现云山雾罩.晦涩难懂的讲解,代之以轻松活泼.由浅入 ...
- 双数组trie树的基本构造及简单优化
一 基本构造 Trie树是搜索树的一种,来自英文单词"Retrieval"的简写,可以建立有效的数据检索组织结构,是中文匹配分词算法中词典的一种常见实现.它本质上是一个确定的有限状 ...
- [mysql] 2进制安装和简单优化
##################################mysql 2进制安装和简单优化################################################## ...
- 封装ajax,让调用变得简单优化
思考一下: 通常我们在使用ajax来发送接口请求时,每一次都会调用ajax固定的元素,比如data.url.method.success.error等.那么我们想一下能不能先把ajax封装起来,在每次 ...
- linux简单优化
1.简单优化 #关闭firewalld,selinux,NetworkManager systemctl(管理服务的命令) stop(关服务) firewalld (服务名称,d是demo的意思) s ...
随机推荐
- 签名、BOM头、编码、Windows记事本编码、java编码解码的那些事
对于Windows记事本: ANSI :GB2312 java中应使用GBK解码 Unicode :有签名的UTF-16LE java中应使用UTF-16解码 Unicode big endian : ...
- 1.1ASP.NET Web API 2入门
HTTP 不只是为了生成 web 页面.它也是建立公开服务和数据的 Api 的强大平台.HTTP 是简单的. 灵活的和无处不在.你能想到的几乎任何平台有 HTTP 库,因此,HTTP 服务可以达到范围 ...
- rails enum用于存储数据
http://api.rubyonrails.org/classes/ActiveRecord/Enum.html 新的项目中有一个字段是展示类型,可以用下拉框去做,用string存储具体的类型字段. ...
- GET和POST可传递的值到底有多大?
前日,看到这个问题了. 没有深入了解.我的常识里面get最大传递的值为256b,post 是2M.这是很久以前不知在哪看到的.于是又百度一下.看到两篇文章装过来看看: 浅谈 HTTP中Get与Post ...
- [BZOJ4408][Fjoi 2016]神秘数
[BZOJ4408][Fjoi 2016]神秘数 试题描述 一个可重复数字集合S的神秘数定义为最小的不能被S的子集的和表示的正整数.例如S={1,1,1,4,13},1 = 12 = 1+13 = 1 ...
- PHP程序员进阶学习书籍参考指南
PHP程序员进阶学习书籍参考指南 @heiyeluren lastmodify: 2016/2/18 [初阶](基础知识及入门) 01. <PHP与MySQL程序设计(第4版)> ...
- Eclipse 的单步调试
1.设置断点在程序里面放置一个断点,也就是双击需要放置断点的程序左边的栏目上. 2.调试(1)点击"打开透视图"按钮,选择调试透视图,则打开调试透视图界面,然后先设置断点,按调试按 ...
- servlet 之request
request对象中其他功能 一.转发和包含 转发==>用于一个servlet和一个jsp合作处理 servlet用于处理逻辑.jsp用于显示 ...
- October 15th 2016 Week 42nd Saturday
Word to World. There are only two kinds of people who are really fascinating, people who know absolu ...
- LeetCode之383. Ransom Note
-------------------------------------------- 思路就是进行频率统计. 统计一下第二个字符串字符出现次数++统计一下第一个字符串中字符出现次数--如果出现负数 ...
1 package com.cn.shupu.util;
import java.io.BufferedReader;