`
Weich_JavaDeveloper
  • 浏览: 100093 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Lucene 扩展

阅读更多
目的:在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的应用程序扩展

    **Lucene 应用程序扩展在 ASP.NET 中的实践与应用** Lucene 是一个高性能、全文本搜索库,由 Apache 软件基金会开发。它提供了强大的搜索功能,被广泛应用于各种应用程序,包括网站、数据库和文档管理。在 ASP.NET ...

    Lucene 3.6 学习笔记

    ### 第六章 Lucene 扩展 #### 6.1 Luke - Luke是Lucene的可视化工具,用于查看和分析索引。 - 可以查看索引结构、文档信息、查询等。 #### 6.2 Tika - Tika是Apache的元数据提取库,可解析多种文件格式并提取文本...

    lucene搜索引擎【代码以及jar包】

     (3)优秀的面向对象的系统架构,使得对于Lucene扩展的学习难度降低,方便扩充新功能。  (4)设计了独立于语言和文件格式的文本分析接口,索引器通过接受Token流完成索引文件的创立,用户扩展新的语言和文件格式...

    基于LUCENE的搜索引擎的设计与实现源代码

    五、LUCENE扩展与优化 1. 高级查询:LUCENE支持布尔查询、短语查询、近似查询等多种复杂的查询模式,以及评分函数和自定义相似度模型。 2. 分布式搜索:通过Solr或Elasticsearch,LUCENE可以扩展到分布式环境,...

    Lucene in Action 2nd Edition MEAP Jun 2010

    必备的Lucene扩展** - **排序和过滤**:介绍了如何使用Lucene的扩展功能来进行更复杂的排序和过滤操作。 - **高性能查询**:讨论了如何利用扩展功能提高查询性能。 **9. 更多Lucene扩展** - **地理空间搜索**:...

    windows+php+lucene

    在Windows环境下,你可以使用PHP的Lucene扩展(如`php-lucene`)来与Lucene库进行交互。这个扩展提供了一系列的类和方法,使PHP开发者能够方便地创建、更新和查询Lucene索引。 描述中提到的博文链接可能提供了关于...

    lucene学习-02

    - **Lucene扩展**:如Elasticsearch、Solr等基于Lucene的框架,提供更高级的功能和服务,如集群管理、REST API和更多配置选项。 通过对“Lucene学习-02”的深入学习,你可以掌握这些关键点,并能够应用到实际项目中...

    Lucene 原理与代码分析完整版

    五、Lucene扩展与优化 1. Solr与Elasticsearch:基于Lucene构建的更高级的搜索服务器,提供更丰富的功能,如分布式搜索、多租户支持、内置的集群管理等。 2. 索引优化:定期合并小段以减少磁盘I/O,或者使用自定义...

    Lucene in action 2nd Edition MEAP(英文版第二版)

    6. **Lucene扩展与集成**:介绍如何在实际项目中集成Lucene,如Spring Data Lucene,以及如何利用Solr或Elasticsearch这样的高级搜索平台来扩展Lucene的功能。 7. **性能调优**:提供实用的性能优化建议,包括硬件...

    lucene4 solr4j arIk4

    最后,AriK4是一个用于地理空间信息检索的库,它基于Lucene扩展了空间搜索能力。AriK4的主要特点包括: 1. 空间索引:AriK4引入了空间索引结构,如R树或quadtree,以支持高效的范围查询和邻近搜索。 2. 地理编码:...

    计算机专业外文翻译(lucene相关)

    Lucene是一个高性能的、可扩展的搜索引擎,可以对大量的文档进行索引和搜索。 Nutch/Lucene 论文中使用了Nutch/Lucene来实现非结构化数据的检索。Nutch是一个爬虫工具,可以从互联网上爬取大量的网页,然后使用...

    lucene-4.7.0全套jar包

    - **Contrib模块**:包含社区贡献的扩展功能,可能包括特殊分词器、搜索建议等,如`lucene-join-4.7.0.jar`、`lucene-suggest-4.7.0.jar`等。 使用这些JAR包时,开发者需要根据具体需求选择合适的模块,并确保它们...

    Lucene简介.介绍

    例如,你可以自定义查询分析器、实现删除操作、扩展排序机制,以及利用 Lucene 的 API 接口扩展应用功能。 总之,Lucene 是一个强大且灵活的全文搜索库,为 Java 开发者提供了在各种应用中实现高效全文检索的工具。...

    正向最大匹配中文分词算法

    而且不少中文分词软件支持Lucene扩展。但不管实现如何,目前而言的分词系统绝大多数都是基于中文词典的匹配算法。其中最为常见的是最大匹配算法 (Maximum Matching,以下简称MM算法) 。MM算法有三种:一种正向最大...

    Lucene in Action 中文版

    第2版 》基于Apache的Lucene 3 0 从Lucene核心 Lucene应用 案例分析3个方面详细系统地介绍了Lucene 包括认识Lucene 建立索引 为应用程序添加搜索功能 高级搜索技术 扩展搜索 使用Tika提取文本 Lucene的高级扩展 ...

    lucene

    2. 分布式搜索(Distributed Search):通过Solr或Elasticsearch等工具,Lucene可以扩展到分布式环境,处理大规模数据。 3. 高级搜索特性:支持多字段搜索、过滤器查询、自定义评分函数等。 五、实际应用 Lucene常...

    lucene所有的jar包

    “my的jar包”通常指的是开发人员自定义的扩展或封装,可能包含了对Lucene原生功能的增强或者针对特定需求的定制化处理。这些jar包可能包含自定义的分析器、查询解析器、过滤器等,是开发者根据实际项目需求进行的二...

Global site tag (gtag.js) - Google Analytics