您的位置:首页 > 其它

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

2017-11-12 12:48 525 查看
前面我们也使用用到了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() thr
d1b4
ows 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();
}

运行结果如下:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: