进一步说明Lucene代码及优化代码

我们的Lucene程序就是大概这么一个思路:将JavaBean对象封装到Document对象中,然后通过IndexWriter把document写入到索引库中。当用户需要查询的时候,就使用IndexSearcher从索引库中读取数据,找到对应的Document对象,从而解析里边的内容,再封装到JavaBean对象中让我们使用。

这里写图片描述

二、对Lucene代码优化
我们再次看回我们上一篇快速入门写过的代码,我来截取一些有代表性的:

以下代码在把数据填充到索引库,和从索引库查询数据的时候,都出现了。是重复代码!

 Directory directory = FSDirectory.open(new File("E:/createIndexDB"));
 //使用标准的分词算法对原始记录表进行拆分
        Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_30);

以下的代码其实就是将JavaBean的数据封装到Document对象中,我们是可以通过反射来对其进行封装….如果不封装的话,我们如果有很多JavaBean都要添加到Document对象中,就会出现很多类似的代码。

 //将Document对象中的所有属性取出,再封装回JavaBean对象中去
           String id = document.get("id");
           String userName = document.get("userName");
           String sal = document.get("sal");
           User user = new User(id, userName, sal);

2.1编写Lucene工具类
在编写工具类的时候,值得注意的地方:

当我们得到了对象的属性的时候,就可以把属性的get方法封装起来
得到get方法,就可以调用它,得到对应的值
在操作对象的属性时,我们要使用暴力访问
如果有属性,值,对象这三个变量,我们记得使用BeanUtils组件

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.index.IndexWriter;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import org.junit.Test;

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

/**
 * Created by ozc on 2017/7/12.
 */

/**
 * 使用单例事例模式
 * */
public class LuceneUtils {
    private static Directory directory;
    private static Analyzer analyzer;
    private static IndexWriter.MaxFieldLength maxFieldLength;

    private LuceneUtils() {}

    static{
        try {
            directory = FSDirectory.open(new File("E:/createIndexDB"));
            analyzer = new StandardAnalyzer(Version.LUCENE_30);
            maxFieldLength = IndexWriter.MaxFieldLength.LIMITED;
        } catch (Exception e) {
            e.printStackTrace();

        }
    }

    public static Directory getDirectory() {
        return directory;
    }

    public static Analyzer getAnalyzer() {
        return analyzer;
    }

    public static IndexWriter.MaxFieldLength getMaxFieldLength() {
        return maxFieldLength;
    }

    /**
     * @param object 传入的JavaBean类型
     * @return 返回Document对象
     */
    public static Document javaBean2Document(Object object) {
        try {
            Document document = new Document();
            //得到JavaBean的字节码文件对象
            Class<?> aClass = object.getClass();

            //通过字节码文件对象得到对应的属性【全部的属性,不能仅仅调用getFields()】
            Field[] fields = aClass.getDeclaredFields();

            //得到每个属性的名字
            for (Field field : fields) {
                String name = field.getName();
                //得到属性的值【也就是调用getter方法获取对应的值】
                String method = "get" + name.substring(0, 1).toUpperCase() + name.substring(1);
                //得到对应的值【就是得到具体的方法,然后调用就行了。因为是get方法,没有参数】
                Method aClassMethod = aClass.getDeclaredMethod(method, null);
                String value = aClassMethod.invoke(object).toString();
                System.out.println(value);


                //把数据封装到Document对象中。
                document.add(new org.apache.lucene.document.Field(name, value, org.apache.lucene.document.Field.Store.YES, org.apache.lucene.document.Field.Index.ANALYZED));
            }
            return document;
        }  catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * @param aClass   要解析的对象类型,要用户传入进来
     * @param document 将Document对象传入进来
     * @return 返回一个JavaBean
     */
    public static Object Document2JavaBean(Document document, Class aClass) {
        try {
            //创建该JavaBean对象
            Object obj = aClass.newInstance();
            //得到该JavaBean所有的成员变量
            Field[] fields = aClass.getDeclaredFields();
            for (Field field : fields) {

                //设置允许暴力访问
                field.setAccessible(true);
                String name = field.getName();
                String value = document.get(name);
                //使用BeanUtils把数据封装到Bean中
                BeanUtils.setProperty(obj, name, value);
            }
            return obj;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    @Test
    public void test() {
        User user = new User();
        LuceneUtils.javaBean2Document(user);
    }

}

2.2使用LuceneUtils改造程序

@Test
    public void createIndexDB() throws Exception {
        //把数据填充到JavaBean对象中
        User user = new User("2", "钟福成2", "未来的程序员2");
        Document document = LuceneUtils.javaBean2Document(user);
        /**
         * IndexWriter将我们的document对象写到硬盘中
         *
         * 参数一:Directory d,写到硬盘中的目录路径是什么
         * 参数二:Analyzer a, 以何种算法来对document中的原始记录表数据进行拆分成词汇表
         * 参数三:MaxFieldLength mfl 最多将文本拆分出多少个词汇
         *
         * */
        IndexWriter indexWriter = new IndexWriter(LuceneUtils.getDirectory(), LuceneUtils.getAnalyzer(), LuceneUtils.getMaxFieldLength());

        //将Document对象通过IndexWriter对象写入索引库中
        indexWriter.addDocument(document);
        //关闭IndexWriter对象
        indexWriter.close();
    }


    @Test
    public void findIndexDB() throws Exception {


        //创建IndexSearcher对象
        IndexSearcher indexSearcher = new IndexSearcher(LuceneUtils.getDirectory());
        //创建QueryParser对象
        QueryParser queryParser = new QueryParser(Version.LUCENE_30, "userName", LuceneUtils.getAnalyzer());
        //给出要查询的关键字
        String keyWords = "钟";
        //创建Query对象来封装关键字
        Query query = queryParser.parse(keyWords);
        //用IndexSearcher对象去索引库中查询符合条件的前100条记录,不足100条记录的以实际为准
        TopDocs topDocs = indexSearcher.search(query, 100);
        //获取符合条件的编号
        for (int i = 0; i < topDocs.scoreDocs.length; i++) {
            ScoreDoc scoreDoc = topDocs.scoreDocs[i];
            int no = scoreDoc.doc;
            //用indexSearcher对象去索引库中查询编号对应的Document对象
            Document document = indexSearcher.doc(no);
            //将Document对象中的所有属性取出,再封装回JavaBean对象中去
            User user = (User) LuceneUtils.Document2JavaBean(document, User.class);
            System.out.println(user);

        }
    }

猜你喜欢

转载自blog.csdn.net/weixin_41653442/article/details/81508507