您的位置:首页 > 其它

简单封装Lucenene的IndexWriter、IndexSearcher对象

2014-03-22 21:27 369 查看
导包以下4个包:



封装类

package cn.lhzd.test;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field.Index;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.queryParser.MultiFieldQueryParser;
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.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;

/**
*
* @author hubiao
* @date:2014-03-22 1:封装IndexWrite、IndexSearcher对象。只初始化一次 2:在结束JVM时释放资源
*
*/
public class luceneUtils {

private static String savaIndexPath = "./indexWrite";

/* 增、删、改 */
private static IndexWriter indexWriter;

/* 执行查询 */
private static IndexSearcher indexSearcher;

/*分词器*/
private static Analyzer analyzer;

/*目录*/
private static Directory directory;

static {
try {
// 创建保存目录、分词器
directory = FSDirectory.open(new File(savaIndexPath));
analyzer = new StandardAnalyzer(Version.LUCENE_36);
//监听线程,当JVM结束时,就执行此线程。释放资源
Runtime.getRuntime().addShutdownHook(new Thread(){
public void run(){
closeIndexWrite();
closeIndexSearcher();
}
});
} catch (IOException e) {
e.printStackTrace();
}
}

public static IndexWriter getIndexWriter() {
if(indexWriter==null){
try {
IndexWriterConfig indexCpnfig = new IndexWriterConfig(Version.LUCENE_36, analyzer);
indexWriter = new IndexWriter(directory, indexCpnfig);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
return indexWriter;
}

/*关闭indexWrite*/
public static void closeIndexWrite(){
if(indexWriter!=null){
System.out.println("关闭indexWriter对象");
try {
indexWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static IndexSearcher getIndexSearcher(){
if(indexSearcher==null){
try {
indexSearcher = new IndexSearcher(IndexReader.open(FSDirectory.open(new File(savaIndexPath))));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
return indexSearcher;
}

/*关闭indexSearcher*/
public static void closeIndexSearcher(){
if(indexSearcher!=null){
System.out.println("关闭indexSearcher对象");
try {
indexSearcher.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

/* 添加索引
*   array 添加的索引值
*   write 操作索引对象
*/
@SuppressWarnings("rawtypes")
public static void addDocument(List<Object> array,IndexWriter write) {
Document doc = new Document();
for (Object ins : array) {
Class clazz = ins.getClass();
Field[] fields = clazz.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
Field field = fields[i];
//根据属性获取方法名、把值赋给指定set方法
String name = field.getName();
String fieldName = name.substring(0,1).toUpperCase();
fieldName = String.format("get%s%s", fieldName,name.substring(1));
try{
Method method = clazz.getMethod(fieldName);
Object aaa = method.invoke(ins);
doc.add(new org.apache.lucene.document.Field(name,aaa.toString(),Store.YES,Index.ANALYZED));
}catch(Exception ex){
throw new RuntimeException(String.format("找不到{0},异常信息:{1}",fieldName,ex.getMessage()));
}
}
}
try {
write.addDocument(doc);
write.commit();//提交
} catch (Exception e) {
e.printStackTrace();
}
}
/* 查询索引
*		param:索引字段参数
*		paramObj:匹配值
*		searcher:查询索引对象
*		clazz:把索引值都包装到指定对象的
*return List:符合条件的对象
*/
@SuppressWarnings({"rawtypes","unchecked"})
public static List selectDocument(String[] param,String paramObj,IndexSearcher searcher,Class clazz) {
//包装数据的容器
List array = new ArrayList();

//创建搜索对象
MultiFieldQueryParser parserObject = new MultiFieldQueryParser(Version.LUCENE_36,param,analyzer);

try {
Query query = parserObject.parse(paramObj);
TopDocs search = searcher.search(query, 100);
System.out.println("查询到记录:"+search.totalHits+"条");
ScoreDoc[] scoreDocs = search.scoreDocs;

for (int x = 0; x < scoreDocs.length; x++) {
Object instance = clazz.newInstance();
ScoreDoc scoreDoc = scoreDocs[x];
//获取索引位置
int doc = scoreDoc.doc;
Document document = searcher.doc(doc);
Field[] fields = clazz.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
Field field = fields[i];
//根据属性获取方法名、把值赋给指定set方法
String name = field.getName();
String fieldName = name.substring(0,1).toUpperCase();
fieldName = String.format("set%s%s", fieldName,name.substring(1));
try{
Method method = clazz.getMethod(fieldName, field.getType());
String st = document.get(name);
Class type = field.getType();
Constructor constructor = type.getConstructor(String.class);
Object newInstance = constructor.newInstance(st);
method.invoke(instance,new Object[]{newInstance});
}catch(Exception ex){
throw new RuntimeException(String.format("找不到%s,异常信息:%s",fieldName,ex.getMessage()));
}
}

array.add(instance);
}
}catch(Exception ex){
throw new RuntimeException(ex);
}

return array;
}
}
测试代码
//写入
@Test
public void writeIndex() throws Exception
{

IndexWriter indexWriter = luceneUtils.getIndexWriter();
List array  = new ArrayList();
Post post = new Post();
post.setId(88l);
post.setTitle("为什么要喜欢lucene");
post.setContext("因为全文检索(Full-Text Retrieval)是指以文本作为检索对象,找出含有指定词汇的文本。全面、准确和快速是衡量全文检索系统的关键指标。");
User user = new User();
user.setId(2l);
user.setTitle("各个国家的首都在哪里?");
user.setContext("世界各国首都: 亚洲各国首都:中国(北京)、日本(东京)、韩国(首尔)、朝鲜(平壤)、泰国(曼谷)、印度(新德里)、越南(河内)、缅甸(仰光)、孟加拉(达卡)..");
array.add(user);
array.add(post);
luceneUtils.addDocument(array, indexWriter);
}

//读取
@Test
public void readIndex() throws ClassNotFoundException{
IndexSearcher searcher = luceneUtils.getIndexSearcher();
List<Post> array = luceneUtils.selectDocument(new String[]{"title"}, "为什么要喜欢lucene", searcher, Post.class);

for (Post p : array) {
System.out.println(p);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: