【Lucene】使用反射技术优化Lucene索引库的查询与创建

前面我们也使用用到了Lucene索引库的创建和查询,发现其代码太繁琐,有太多重复代码

例如:

1.获取Directory、Analyzer、MaxFieldLength、Version对象

2.将javabean对象封转成document对象

3.将document对象封转成javabean对象


接下来我们就创建一个LuceneUtil对索引库的创建和查询进行优化

package cn.qblank.util;

import java.io.File;
import java.lang.reflect.Method;

import org.apache.commons.beanutils.BeanUtils;
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;
import org.apache.lucene.document.Field.Index;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.index.IndexWriter.MaxFieldLength;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;

/**
 * Lucene工具类
 * @author Administrator
 *
 */
public class LuceneUtil {
	private static Directory directory ;
	private static Analyzer analyzer ; 
	private static Version version; 
	private static MaxFieldLength maxFieldLength;
	
	static{
		try {
			directory = FSDirectory.open(new File("F:/LuceneDB"));
			version = Version.LUCENE_30;
			analyzer = new StandardAnalyzer(version);
			maxFieldLength = MaxFieldLength.LIMITED;
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * javabean转docment
	 * @param obj
	 * @return
	 * @throws Exception
	 */
	public static Document javabean2documemt(Object obj) throws Exception{
		//创建document对象
		Document document = new Document();
		//获取字节码对象
		Class clazz = obj.getClass();
		//获取该对象中的私有属性: 使用强反射  这里使用类全称,防止和Lucene包起冲突
		java.lang.reflect.Field[] reflectfields = clazz.getDeclaredFields();
		
		//遍历字段
		for (java.lang.reflect.Field field : reflectfields) {
			//设置访问权限:因为字段是私有的
			field.setAccessible(true);
			String fieldName = field.getName();
			//给其拼装成get方法
			String methodName = "get" + fieldName.substring(0,1).toUpperCase() + fieldName.substring(1);
			
			Method method = clazz.getMethod(methodName, null);
			//调用方法
			String returnValue = method.invoke(obj, null).toString();
			
			document.add(new Field(fieldName, returnValue, Store.YES, Index.ANALYZED));
		}
		
		
		return document;
	}
	
	/**
	 * document转javabean,可以使用BeanUtils组件
	 * @throws Exception
	 */
	public static Object document2javabean(Document document,Class clazz) throws Exception{
		//先获取字节码对象
		Object obj = clazz.newInstance();
		//获取到各个字段名
		java.lang.reflect.Field[] reflectField = clazz.getDeclaredFields();
		for (java.lang.reflect.Field field : reflectField) {
			//设置访问权限
			field.setAccessible(true);
			//获取各个的字段名和值
			String fieldName = field.getName();
			String fieldValue = document.get(fieldName);
			//使用BeanUtils组件封装对象
			BeanUtils.setProperty(obj, fieldName, fieldValue);
		}
		return obj;
	}
	
	
	public static Directory getDirectory() {
		return directory;
	}
	public static Analyzer getAnalyzer() {
		return analyzer;
	}
	public static Version getVersion() {
		return version;
	}
	public static MaxFieldLength getMaxFieldLength() {
		return maxFieldLength;
	}
}

接下来我们继续进行创建和查询索引库

创建索引库优化

public void createIndexDB() throws Exception {
	Article article = new Article(3, "好室友版", "好室友就是我,我就是好室友");
	//将javabean封装成documment对象
	Document document = LuceneUtil.javabean2documemt(article);
	//创建IndexWriter对象
	IndexWriter indexWriter = new IndexWriter(LuceneUtil.getDirectory(), LuceneUtil.getAnalyzer(), LuceneUtil.getMaxFieldLength());
	//将document写入Lucene索引库
	indexWriter.addDocument(document);
	//关闭indexWriter
	indexWriter.close();
}

查询索引库优化

public void findIndexDB() throws Exception {
	//存放封转结果对象的集合
	List<Article> arrayList = new ArrayList<Article>();
	//准备输入的值
	BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	String keywords = br.readLine();
	
	//创建IndexSearcher字符流对象
	IndexSearcher indexSearcher = new IndexSearcher(LuceneUtil.getDirectory());
	//创建QueryParser对象
	QueryParser queryParser = new QueryParser(LuceneUtil.getVersion(), "content", LuceneUtil.getAnalyzer());
	//封转输入的数据
	Query query = queryParser.parse(keywords);
	//使用indexSearcher查询前100条记录
	TopDocs topDocs = indexSearcher.search(query, 100);
	//迭代出词汇表中符合条件的编号
	for (int i = 0; i < topDocs.scoreDocs.length; i++) {
		//取出封装编号和分数的ScoreDoc对象
		ScoreDoc scoreDoc = topDocs.scoreDocs[i];
		//获取结果编号
		int id = scoreDoc.doc;
		//根据编号去原始记录表中查询对应的document对象
		Document document = indexSearcher.doc(id);
		//将docuement对象封转成javabean
		Article article = (Article) LuceneUtil.document2javabean(document, Article.class);
		//将对象添加到集合中
		arrayList.add(article);
	}
	
	//遍历结果集合
	for (Article article : arrayList) {
		System.out.println(article);
	}
	//关闭indexSearcher流对象
	indexSearcher.close();
}


运行结果如下:









  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值