//---------------------------创建索引
public class IndexWrite {
private IndexWrite() {}
public static String index () throws IOException {
//要创建索引目录:F:/search/index_create
File indexDirectory = new File (Common.INDEX_PATH + Common.INDEX_CREATE_DIRECTORY);
//判断目录是否从在
if (indexDirectory.exists()) {
return "此目录 ("+Common.INDEX_PATH + Common.INDEX_CREATE_DIRECTORY+ ")已经存在,如果要重新创建索引,请删掉此目录!";
}
//创建索引目录
indexDirectory.mkdirs();
//获得创建索引的路径
Directory directory = FSDirectory.open(indexDirectory);
//获得要查询数据的接口
CompanyService iCompany = (CompanyService) BeanFactory.getBean("iCompany");
//查询数据的结果集总数
int count = iCompany.queryCount();
//结果集总数大于零创建索引
if(count>0) {
//结果集总数太大,分批创建索引 createNum为创建索引循环的次数
int createNum = count / Common.RECORD_SIZE;
if (count % Common.RECORD_SIZE > 0) {
createNum = createNum + 1;
}
//创建索引的开始时间
long starttime = System.currentTimeMillis();
//分批次循环创建索引
for (int i=1; i<createNum+1; i++) {
//创建硬盘索引
IndexWriter FSDWriter = null;
if (i == 1) {
/*
* directory:要创建索引的路径
* new IKAnalyzer():分词器
* true:新建索引, false是在原有的基础上累加
* IndexWriter.MaxFieldLength.LIMITED:索引字段的最大限制长度
*/
FSDWriter = new IndexWriter(directory, new IKAnalyzer(), true, IndexWriter.MaxFieldLength.LIMITED);
} else {
FSDWriter = new IndexWriter(directory, new IKAnalyzer(), false, IndexWriter.MaxFieldLength.LIMITED);
}
//创建内存索引
IndexWriter RAMWriter = new IndexWriter(new RAMDirectory(), new IKAnalyzer(), true, IndexWriter.MaxFieldLength.LIMITED);
//开始创建内容索引
Directory RAMDirectory = RAMIndexDirectory(RAMWriter, i, count, iCompany);
//关闭内容索引
RAMWriter.close();
//将内存索引添加到硬盘索引
FSDWriter.addIndexesNoOptimize(new Directory[] {RAMDirectory});
//关闭硬盘索引
FSDWriter.close();
}
//开始做文件夹替换
replaceFolder();
long endtime = System.currentTimeMillis();
return "创建索引耗时:" + (endtime - starttime) + "毫秒";
} else {
return "没有要创建索引的记录。";
}
}
public static Directory RAMIndexDirectory (IndexWriter RAMWriter, int createNum, int count, CompanyService iCompany) throws CorruptIndexException, IOException {
//每次循环的开始记录
int start = (createNum - 1) * Common.RECORD_SIZE;
if (start != 0) {
start = start + 1;
}
//每次循环的末记录
int end = Math.min(start + Common.RECORD_SIZE, count);
//查询结果集
List<Company> list = iCompany.query(start, end);
//循环索引并添加到内存
for (int i=0; i<list.size(); i++) {
Company company = list.get(i);
RAMWriter.addDocument(FileDocument.document(company.getTitle(), company.getContent(), company.getUrl(), Common.gmdate("yyyy-MM-dd", company.getLastdate(), "8")));
System.out.println(i++);
}
//对索引进行优化
RAMWriter.optimize();
return RAMWriter.getDirectory();
}
public static void replaceFolder () {
//复制索引路径
File indexCopy = new File(Common.INDEX_PATH + Common.INDEX_COPY_DIRECTORY);
//查询索引路径
File index = new File(Common.INDEX_PATH + Common.INDEX_DIRECTORY);
//创建索引类型
File indexCreate = new File(Common.INDEX_PATH + Common.INDEX_CREATE_DIRECTORY);
//indexCopy存在 删除, 将index 命名为indexCopy, 将indexCreate 命名为index
if (indexCopy.exists()) {
deleteDiretory(indexCopy);
index.renameTo(indexCopy);
indexCreate.renameTo(index);
} else {
index.renameTo(indexCopy);
indexCreate.renameTo(index);
}
}
//删除文件,目录
public static void deleteDiretory (File indexCopy) {
File[] files = indexCopy.listFiles();
for (int i=0; i>files.length; i++) {
if (files[i].isDirectory()) {
deleteDiretory(files[i]);
} else {
files[i].delete();
}
}
}
}
//-------------------------------查询
public class IndexRead {
private IndexRead () {};
public static void search (HttpServletRequest request, String keyword, String pageNo) throws CorruptIndexException, IOException, ParseException, InvalidTokenOffsetsException {
//查询结果总数
int searchTotals = 0;
if (!Common.empty(keyword)) {
if (keyword.contains("%")) {
keyword = Common.decode(keyword);
}
}
//当前页码
int pageNum;
if (Common.empty(pageNo)) {
pageNum = 1;
} else {
keyword = new String (keyword.getBytes("ISO-8859-1"), "utf-8");
}
try {
int i = Integer.parseInt(pageNo);
if (i < 0) {
pageNum = 1;
} else {
pageNum = i;
}
} catch (NumberFormatException e) {
pageNum = 1;
}
Date start = new Date();
//创建索引搜索器
Searcher searcher = new IndexSearcher(FSDirectory.open(new File(Common.INDEX_PATH + "index")));
//创建多条件索引分析器
QueryParser parser = new MultiFieldQueryParser(Version.LUCENE_CURRENT, new String[] {"title", "content"}, new IKAnalyzer());
//创建查询
Query query = parser.parse(keyword);
//排序
Sort sort = new Sort();
SortField sortField = new SortField("lastTime", SortField.STRING, true);
sort.setSort(sortField);
//结果集 searcher.maxDoc():查询的结果总数, false代表查询的结果不排序, true是排序
TopScoreDocCollector collector = TopScoreDocCollector.create(searcher.maxDoc(), false);
//开始查询
searcher.search(query, collector);
//查询到得所有记录
ScoreDoc[] hits = collector.topDocs().scoreDocs;
//记录总数
searchTotals = collector.getTotalHits();
if (searchTotals <= 0) {
request.setAttribute("message", "没有您要查找的内容");
}
//对查询到的结果分页
PageBean pageBean = new PageBean(pageNum, searchTotals, "ss.action?keyword="+(keyword.contains("%") ? keyword:Common.encode(keyword)), 0, 0);
//设置高亮显示
Highlighter highlighter = new Highlighter (new SimpleHTMLFormatter("<b><font color=\"red\">", "</font></b>"), new QueryScorer(query));
highlighter.setTextFragmenter(new SimpleFragmenter(100));
List<Company> list = new ArrayList<Company>();
int endNo = Math.min(pageBean.getStartRecord()+pageBean.getPageSize(), collector.getTotalHits());
for (int i=pageBean.getStartRecord(); i<endNo; i++) {
Document doc = searcher.doc(hits[i].doc);
Company company = new Company();
StringBuffer bufferTitle = new StringBuffer();
TokenStream sTokenStreamTitle = new IKAnalyzer().tokenStream("title", new StringReader(doc.get("title")));
String[] titles = highlighter.getBestFragments(sTokenStreamTitle, doc.get("title"), 50);
if (titles.length == 0) {
company.setTitle(doc.get("title").substring(0, Math.min(50, doc.get("title").length())));
} else {
for (int j=0; j<titles.length; j++) {
bufferTitle.append(titles[j]);
}
company.setTitle(bufferTitle.toString());
}
StringBuffer bufferContent = new StringBuffer();
TokenStream sTokenStreamContent = new IKAnalyzer().tokenStream("content", new StringReader(doc.get("content")));
String[] contents = highlighter.getBestFragments(sTokenStreamContent, doc.get("content"), 50);
if (contents.length == 0) {
company.setContent(doc.get("content").substring(0, Math.min(50, doc.get("content").length())));
} else {
for (int j=0; j<contents.length; j++) {
bufferContent.append(contents[j]);
}
company.setContent(bufferContent.toString());
}
company.setUrl(doc.get("url"));
list.add(company);
}
Date end = new Date();
request.setAttribute("keyword", keyword);
request.setAttribute("page", pageBean);
request.setAttribute("pageStr", pageBean.toString());
request.setAttribute("date", end.getTime() - start.getTime());
request.setAttribute("result", list);
}
}
分享到:
相关推荐
以下是一个简单的Java代码示例,展示了如何创建和使用Lucene索引器: ```java import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.document.Document; import org.apache....
**Lucene索引和查询** Lucene是Apache软件基金会的开放源码全文...本项目提供了一个基础的实现示例,对于初学者来说,是学习Lucene索引和查询的绝佳起点。在实际应用中,可以进一步扩展和优化,以满足更复杂的需求。
**Lucene5学习之创建索引入门示例** 在IT领域,搜索引擎的开发与优化是一项关键技术,而Apache Lucene作为一款高性能、全文本搜索库,是许多开发者进行文本检索的首选工具。本文将深入探讨如何使用Lucene5来创建一...
在提供的示例中,`lucene-demos-1.4-final`包含了对普通文本和HTML文件的索引示例,而`XMLIndexingDemo`则专门处理XML文件。这些示例代码可以帮助开发者理解如何使用Lucene构建索引,以及如何执行搜索操作。 总结来...
二、Lucene索引创建流程 1. 初始化:首先,我们需要导入Lucene库,并创建一个标准的Analyzer,例如StandardAnalyzer,它对输入的文本进行标准化处理。 2. 创建索引目录:索引数据会存储在一个Directory对象中,...
**luke——Lucene索引数据查看器** Luke是一款强大的Lucene索引浏览器,它为开发者和搜索引擎优化人员提供了一种直观的方式来查看和分析由Apache Lucene创建的索引。Lucene是一个开源全文检索库,广泛应用于各种...
在这个示例中,可能涉及将数据库中的数据转换为Lucene索引的过程。 2. **Analyzer**:分析器负责将输入文本分解成词项(tokens),进行标准化处理,如分词、去除停用词、词形还原等。在与SQL Server 2005数据库交互...
1. **索引(Indexing)**: Lucene 首先需要对数据进行索引,这个过程会将文本数据转换为倒排索引结构。倒排索引允许快速查找包含特定单词或短语的文档。 2. **文档(Documents)**: 在 Lucene 中,文档是搜索的基本...
从"lucene3.0.3搜索的使用示例"中,你将学习如何编写代码来完成这些任务,包括索引创建、查询构造、搜索执行以及结果处理等。 在压缩包中的示例代码通常会涵盖这些概念,通过实际运行和调试这些代码,你可以深入...
Lucene是一个高性能、可扩展的信息检索库,它提供了完整的搜索功能,包括索引创建、文档存储和查询。在Lucene 6.6.2版本中,优化了性能,增强了稳定性,并对API进行了优化,使得开发者能够更高效地进行文本搜索应用...
**Lucene索引搜索简介** Lucene是Apache软件基金会下的一个开源全文搜索引擎库,它提供了高性能、可扩展的文本搜索功能。Lucene并不是一个完整的搜索引擎,而是一个工具集,允许开发人员在自己的应用程序中实现搜索...
同时,`HelloLucene_delete`这个压缩包文件可能是某个示例项目,通过分析其中的代码,你可以更直观地了解Lucene删除索引的实现方式。 总之,Lucene的删除索引机制是一个复杂但高效的过程,涉及到了位向量、段管理和...
本示例将深入探讨如何在Lucene中实现facet查询,包括区间查询和多维度查询,以及关键概念——key-field-value模型。 **一、Lucene Facet的概念** Facets是信息组织的一种方法,类似于图书馆的分类标签。在搜索结果...
Lucene索引创建是指将文档集合转换为索引的过程。索引是Lucene搜索的核心,它使得搜索引擎能够快速地检索文档。Lucene提供了两种索引方式:内存索引和磁盘索引。内存索引将索引存储在内存中,而磁盘索引将索引存储在...
本文将深入探讨Lucene示例中的BM25相似度计算,旨在帮助初学者理解如何利用Lucene 4.7.1版本构建索引、执行查询,并比较默认的TF-IDF相似度与BM25相似度的区别。 首先,我们需要了解什么是Lucene。Lucene是一个由...
本文将详细介绍如何利用Lucene对XML文档进行索引建立的过程,并通过示例代码具体阐述其实现方法。 #### 二、基础知识 1. **Lucene简介** - Lucene是一个开源的全文搜索引擎库,能够帮助开发者构建应用程序内的搜索...
**Lucene 索引、删除、检索 实例** ...通过运行这个示例,你将更深入地理解Lucene的工作原理,包括如何处理文本、建立索引、删除文档以及执行高效的搜索。这对于使用Lucene进行全文搜索应用的开发至关重要。
#### 反向索引示例 假设我们有以下三个文档: 0:"itiswhatitis" 1:"whatisit" 2:"itisabanana" 构建反向索引后,结果如下: "a":{2} "banana":{2} "is":{0,1,2} "it":{0,1,2} "what":{0,1} 其中,“a...