【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();
}
运行结果如下:
例如:
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();
}
运行结果如下:
相关文章推荐
- JAVAWEB开发之Lucene详解——Lucene入门及使用场景、全文检索、索引CRUD、优化索引库、分词器、高亮、相关度排序、各种查询
- MySQL查询优化技术系列讲座之使用索引(二)
- [转载]使用反射技术动态创建类对象(实例代码)
- Lucene学习之一:使用lucene为数据库表创建索引,并按关键字查询
- Lucene 3.6.1:中文分词、创建索引库、排序、多字段分页查询以及高亮显示
- MySQL查询优化技术之:使用索引
- MySQL查询优化技术之使用索引
- MySQL查询优化技术系列讲座之使用索引【转】
- 设计模式学习(十四)————抽象工厂模式(使用Qt框架的反射技术——根据字符串动态创建类来实现)
- 全文检索之lucene的优化篇--创建索引库
- 使用反射技术动态创建类对象(实例代码)
- DaoFactory(使用反射技术创建Dao的实现类)
- 【Java学习】使用泛型和反射 创建通用的数据库查询方法
- MySQL查询优化技术系列讲座之使用索引
- 使用Lucene开发简单的站内新闻搜索引擎(索引库的创建)
- Lucene创建和查询索引库的HelloWorld(含详细注释)
- MySQL查询优化技术系列讲座之使用索引
- 全文检索之lucene的优化篇--创建索引库
- MySQL查询优化技术系列讲座之使用索引(一)
- MySQL查询优化技术系列讲座之使用索引