目的:在Lucene上扩展创建索引和查询索引功能。(针对数据库)
所需jar包:
lucene-core-2.4.1.jar
lucene-highlighter-2.4.1.jar
log4j-1.2.14.jar
commons-beanutils-1.5.jar
commons-collections-2.1.1.jar
commons-logging-1.0.4.jar
清单一:DocumentFactory.java
/*
* @(#)Documents.java 2009-10-09
*/
package com.ordinov.lucene;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
/**
* 索引文件内容创建类
*
* @author weich
* @Date 2009-10-09
*
*/
public class DocumentFactory {
/**
* 获取数据内容用来建立索引(针对单个对象)<br>
* 默认Bean类中第一个属性处理方式为:建立索引但是不使用分词
*
* @param <T> 实体Bean对象
* @param fields Bean对象的Field属性
* @param obj 需要转换的Bean对象
* @return
* @throws java.io.FileNotFoundException
* @throws IllegalAccessException
* @throws InvocationTargetException
* @throws NoSuchMethodException
*/
public static <T> Document getDataDocument(java.lang.reflect.Field[] fields,T obj)throws java.io.FileNotFoundException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
Document doc = new Document();
doc.add(new Field(fields[0].getName(),BeanUtils.getProperty(obj, fields[0].getName()), Field.Store.YES, Field.Index.NOT_ANALYZED));
for(int i =1; i < fields.length; i++){
doc.add(new Field(fields[i].getName(),BeanUtils.getProperty(obj, fields[i].getName()), Field.Store.YES, Field.Index.ANALYZED));
}
return doc;
}
/**
* 获取数据内容用来建立索引(针对多个对象)<br>
* 默认Bean类中第一个属性处理方式为:建立索引但是不使用分词
*
* @param <T> 实体Bean对象
* @param cls Bean类的Class对象
* @param objs 需要转换的Bean对象数组
* @return
* @throws java.io.FileNotFoundException
* @throws IllegalAccessException
* @throws InvocationTargetException
* @throws NoSuchMethodException
*/
public static <T> Document[] getDataDocuments(Class<T> cls,T[] objs)throws java.io.FileNotFoundException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
List<Document> docs= new ArrayList<Document>();
java.lang.reflect.Field[] fields = cls.getDeclaredFields();
for(T obj : objs)
docs.add(getDataDocument(fields,obj));
return docs.toArray(new Document[0]);
}
}
清单二:IndexManger.java
/*
* @(#)IndexFactory.java 2009-10-09
*/
package com.ordinov.lucene;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import org.apache.log4j.Logger;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.store.LockObtainFailedException;
/**
* 检索工厂类<br>
* 主要负责索引的创建工作,提供检索类调用。
*
* @author weich
* @Date 2009-10-09
*
*/
public class IndexManger {
/** 日志记录器 */
static private Logger logger = Logger.getLogger(IndexManger.class);
/** 分词器 StandardAnalyzer 按字分词,支持中文分词 */
private StandardAnalyzer analyzer = null;
/** 索引写出类对象主要负责索引的创建 */
private IndexWriter writer = null;
/** 是否新建索引 true-新建索引,false-追加索引。默认为true */
private boolean isNewCreat = true;
/** 索引文件保存路径 */
private String indexPath= null;
/** 对搜索结果内容进行过滤,可以禁止搜索部分词汇 */
private String [] stopStrs = {};
/**
* IndexFactory构造器 <br>
* 初始化创建索引文件时必须的一些属性
*
* @throws IOException
* @throws LockObtainFailedException
* @throws CorruptIndexException
*
*/
public IndexManger() throws CorruptIndexException, LockObtainFailedException, IOException{
/* 初始化所需对象实例 */
init();
}
/**
* IndexFactory 构造器<br>
* 初始化创建索引文件时必须的一些属性
*
* @param indexPath 索引文件保存路径
* @param stopStrs 搜索结果过滤词汇
* @param isCreat 是否新创建索引
*
* @throws CorruptIndexException
* @throws LockObtainFailedException
* @throws IOException
*/
public IndexManger(String indexPath,String [] stopStrs,boolean isCreat) throws CorruptIndexException, LockObtainFailedException, IOException{
if(indexPath != null && !"".equals(indexPath)){
this.indexPath=indexPath;
}
if(stopStrs != null && stopStrs.length > 0){
this.stopStrs=stopStrs;
}
this.isNewCreat=isCreat;
/* 初始化所需对象实例 */
init();
}
/**
* 初始化对象实例<br>
* 创建分词器对象以及索引写出对象
*
* @throws CorruptIndexException
* @throws LockObtainFailedException
* @throws IOException
*/
private void init() throws CorruptIndexException, LockObtainFailedException, IOException{
analyzer=new StandardAnalyzer(stopStrs);
writer= new IndexWriter(new File(indexPath),analyzer,this.isNewCreat,IndexWriter.MaxFieldLength.UNLIMITED);
}
/**
* 创建索引文件
*
* @param docs 需要添加到
*
* @throws IOException
* @throws CorruptIndexException
*/
private void addDocs(Document[] docs) throws CorruptIndexException, IOException{
if(docs != null && docs.length > 0){
for(int i=0; i<docs.length;i++){
/* 向IndexWriter对象中加入Document记录 */
this.addDoc(docs[i]);
}
}
}
/**
* 向IndexWriter对象中添加一条Document记录
*
* @param doc 需要在
* @throws IOException
* @throws CorruptIndexException
*/
private void addDoc(Document doc) throws CorruptIndexException, IOException{
/* 向IndexWriter对象中加入Document记录 */
writer.addDocument(doc);
}
/**
* 在磁盘上创建索引文件,并优化合并,最后会关闭IndexWriter对象
*
* @throws IOException
* @throws CorruptIndexException
*/
private void close() throws CorruptIndexException, IOException{
logger.debug("关闭索引写出对象实例...");
/* 将缓存中索引文件写入磁盘,并优化合并。 */
writer.optimize();
/* 关闭IndexWriter对象 */
writer.close();
}
/**
* 创建索引根据用户指定的类型
*
* @param <T>
* @param cls Bean类的Class对象
* @param objs Bean对象数组
* @throws CorruptIndexException
* @throws FileNotFoundException
* @throws IOException
* @throws IllegalAccessException
* @throws InvocationTargetException
* @throws NoSuchMethodException
*/
public <T> void createIndex(Class<T> cls,T[] objs) throws CorruptIndexException, FileNotFoundException, IOException, IllegalAccessException, InvocationTargetException, NoSuchMethodException{
this.addDocs(DocumentFactory.getDataDocuments(cls, objs));
/* 关闭索引写出对象 */
this.close();
}
}
清单三:SerchIndex.java
package com.ordinov.lucene;
import java.io.StringReader;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.queryParser.MultiFieldQueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.MultiSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocCollector;
import org.apache.lucene.search.highlight.Highlighter;
import org.apache.lucene.search.highlight.QueryScorer;
import org.apache.lucene.search.highlight.SimpleFragmenter;
import org.apache.lucene.search.highlight.SimpleHTMLFormatter;
public class SerchIndex {
/**
* 执行查询方法
*
* @param <T> 需要转换的Bean类型
* @param cls Bean类的class对象
* @param keyword 关键字
* @param indexPath 索引所在的目录
* @param rowCount 每页显示的记录数
* @param current 当前需要查看的页数
* @return
* @throws Exception
*/
public <T> List<T> initSearch(Class<T> cls, String keyword, int rowCount,int current, String... indexPaths)throws Exception{
/* 用来保存填充完毕的返回对象 */
List<T> objs = new ArrayList<T>();
/* 分词器 StandardAnalyzer 按字分词,支持中文分词 */
Analyzer analyzer = new StandardAnalyzer();
Field[] fields = cls.getDeclaredFields();
/* 关键字都去匹配那些列 */
String[] colmuns = new String[fields.length];
/* 查询关键字 */
String[] keyWords = new String[fields.length];
for(int i =0;i < fields.length; i++){
colmuns[i] = fields[i].getName();
keyWords[i] = keyword;
}
if(indexPaths == null || indexPaths.length <= 0){
return objs;
}
IndexSearcher[] searchers = new IndexSearcher[indexPaths.length];
for(int i = 0; i < indexPaths.length; i++){
/* 索引读取对象 */
IndexReader reader = IndexReader.open(indexPaths[i]);
/* 创建索引查询对象 */
searchers[i] = new IndexSearcher(reader);
}
MultiSearcher multisearcher = new MultiSearcher(searchers);
Query query = MultiFieldQueryParser.parse(keyWords, colmuns, analyzer);
/* 缓冲记录数 */
TopDocCollector collector = new TopDocCollector(rowCount);
/* 执行查询 */
multisearcher.search(query,collector);
ScoreDoc[] hits = collector.topDocs().scoreDocs;
for(int i = (current - 1) * rowCount;i<current * rowCount; i++){
int docId = hits[i].doc;
Document doc = multisearcher.doc(docId);
T obj = cls.newInstance();
for(int j =0;j < fields.length; j++){
String str = doc.get(fields[j].getName());
/* 搜索关键字高亮处理 */
SimpleHTMLFormatter sHtmlF = new SimpleHTMLFormatter("<font color='red'>", "</font>");
Highlighter highlighter = new Highlighter(sHtmlF,new QueryScorer(query));
highlighter.setTextFragmenter(new SimpleFragmenter(100));
if (str != null && !"".equals(str)) {
TokenStream tokenStream = analyzer.tokenStream(fields[j].getName(), new StringReader(str));
String value = highlighter.getBestFragment(tokenStream, str);
/* 如果不存在关键字依然显示 */
if(value != null && !"".equals(value)){
BeanUtils.setProperty(obj, fields[j].getName(), value);
}else{
BeanUtils.setProperty(obj, fields[j].getName(), str);
}
}
}
objs.add(obj);
}
multisearcher.close();
return objs;
}
}
分享到:
相关推荐
**Lucene 应用程序扩展在 ASP.NET 中的实践与应用** Lucene 是一个高性能、全文本搜索库,由 Apache 软件基金会开发。它提供了强大的搜索功能,被广泛应用于各种应用程序,包括网站、数据库和文档管理。在 ASP.NET ...
### 第六章 Lucene 扩展 #### 6.1 Luke - Luke是Lucene的可视化工具,用于查看和分析索引。 - 可以查看索引结构、文档信息、查询等。 #### 6.2 Tika - Tika是Apache的元数据提取库,可解析多种文件格式并提取文本...
(3)优秀的面向对象的系统架构,使得对于Lucene扩展的学习难度降低,方便扩充新功能。 (4)设计了独立于语言和文件格式的文本分析接口,索引器通过接受Token流完成索引文件的创立,用户扩展新的语言和文件格式...
五、LUCENE扩展与优化 1. 高级查询:LUCENE支持布尔查询、短语查询、近似查询等多种复杂的查询模式,以及评分函数和自定义相似度模型。 2. 分布式搜索:通过Solr或Elasticsearch,LUCENE可以扩展到分布式环境,...
必备的Lucene扩展** - **排序和过滤**:介绍了如何使用Lucene的扩展功能来进行更复杂的排序和过滤操作。 - **高性能查询**:讨论了如何利用扩展功能提高查询性能。 **9. 更多Lucene扩展** - **地理空间搜索**:...
在Windows环境下,你可以使用PHP的Lucene扩展(如`php-lucene`)来与Lucene库进行交互。这个扩展提供了一系列的类和方法,使PHP开发者能够方便地创建、更新和查询Lucene索引。 描述中提到的博文链接可能提供了关于...
- **Lucene扩展**:如Elasticsearch、Solr等基于Lucene的框架,提供更高级的功能和服务,如集群管理、REST API和更多配置选项。 通过对“Lucene学习-02”的深入学习,你可以掌握这些关键点,并能够应用到实际项目中...
五、Lucene扩展与优化 1. Solr与Elasticsearch:基于Lucene构建的更高级的搜索服务器,提供更丰富的功能,如分布式搜索、多租户支持、内置的集群管理等。 2. 索引优化:定期合并小段以减少磁盘I/O,或者使用自定义...
6. **Lucene扩展与集成**:介绍如何在实际项目中集成Lucene,如Spring Data Lucene,以及如何利用Solr或Elasticsearch这样的高级搜索平台来扩展Lucene的功能。 7. **性能调优**:提供实用的性能优化建议,包括硬件...
最后,AriK4是一个用于地理空间信息检索的库,它基于Lucene扩展了空间搜索能力。AriK4的主要特点包括: 1. 空间索引:AriK4引入了空间索引结构,如R树或quadtree,以支持高效的范围查询和邻近搜索。 2. 地理编码:...
Lucene是一个高性能的、可扩展的搜索引擎,可以对大量的文档进行索引和搜索。 Nutch/Lucene 论文中使用了Nutch/Lucene来实现非结构化数据的检索。Nutch是一个爬虫工具,可以从互联网上爬取大量的网页,然后使用...
- **Contrib模块**:包含社区贡献的扩展功能,可能包括特殊分词器、搜索建议等,如`lucene-join-4.7.0.jar`、`lucene-suggest-4.7.0.jar`等。 使用这些JAR包时,开发者需要根据具体需求选择合适的模块,并确保它们...
例如,你可以自定义查询分析器、实现删除操作、扩展排序机制,以及利用 Lucene 的 API 接口扩展应用功能。 总之,Lucene 是一个强大且灵活的全文搜索库,为 Java 开发者提供了在各种应用中实现高效全文检索的工具。...
而且不少中文分词软件支持Lucene扩展。但不管实现如何,目前而言的分词系统绝大多数都是基于中文词典的匹配算法。其中最为常见的是最大匹配算法 (Maximum Matching,以下简称MM算法) 。MM算法有三种:一种正向最大...
第2版 》基于Apache的Lucene 3 0 从Lucene核心 Lucene应用 案例分析3个方面详细系统地介绍了Lucene 包括认识Lucene 建立索引 为应用程序添加搜索功能 高级搜索技术 扩展搜索 使用Tika提取文本 Lucene的高级扩展 ...
2. 分布式搜索(Distributed Search):通过Solr或Elasticsearch等工具,Lucene可以扩展到分布式环境,处理大规模数据。 3. 高级搜索特性:支持多字段搜索、过滤器查询、自定义评分函数等。 五、实际应用 Lucene常...
“my的jar包”通常指的是开发人员自定义的扩展或封装,可能包含了对Lucene原生功能的增强或者针对特定需求的定制化处理。这些jar包可能包含自定义的分析器、查询解析器、过滤器等,是开发者根据实际项目需求进行的二...