lucene 4版本的utils

版权声明:@徐小冠 https://blog.csdn.net/weixin_42114097/article/details/81984727
//   这个是  lucene 4版本的  因为lucene 的6版本有着不同,有修改的地方,可以看我的下一个博客

package cn.itcast.utils;

import java.io.File;
import java.io.IOException;
import java.util.List;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.IndexableField;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.SortField;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.SortField.Type;
import org.apache.lucene.search.highlight.Formatter;
import org.apache.lucene.search.highlight.Highlighter;
import org.apache.lucene.search.highlight.QueryScorer;
import org.apache.lucene.search.highlight.Scorer;
import org.apache.lucene.search.highlight.SimpleHTMLFormatter;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import org.wltea.analyzer.lucene.IKAnalyzer;

//工具类,获取Lucene操作对象
public class LuceneUtils {
    private static final String INDEX_DIR="indexdir";//索引文件存放目录
    private static Directory directory;//索引文件存放目录对象
    private static Analyzer analyzer;//分词器
    private static IndexWriter indexWriter;//索引写对象,单例
    private static IndexReader indexReader;//索引读对象
    
    
    static{
        try {
            //初始化索引文件存放目录对象
            directory=FSDirectory.open(new File(INDEX_DIR));
            //初始化IK分词器
            analyzer = new IKAnalyzer();
            //初始化索引的写配置对象
            IndexWriterConfig indexWriterConfig=new IndexWriterConfig(Version.LATEST, analyzer);
            //初始化索引的写对象
            indexWriter=new IndexWriter(directory, indexWriterConfig);
            // 虚拟机退出时关闭
            Runtime.getRuntime().addShutdownHook(new Thread(){
                @Override
                public void run() {
                    System.out.println("--------关闭IndexWriter中....");
                    try {
                        //关闭写对象
                        indexWriter.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    
                    System.out.println("--------关闭IndexWriter成功....");
                }
            });
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    /**
     * 获取IndexWriter
     * @return
     */
    public static IndexWriter getIndexWriter(){
        return indexWriter;
    }
    /**
     * 获取IndexReader,重用一些旧的 IndexReader
     * @return
     * @throws Exception
     */
    public static IndexReader getIndexReader() throws Exception{
        if(indexReader==null) {
            indexReader = DirectoryReader.open(directory);
        } else {
            // 如果 IndexReader 不为空,就使用 DirectoryReader 打开一个索引变更过的 IndexReader 类
            //如果改变会返回一个新的reader,没有改变返回null
            IndexReader tr = DirectoryReader.openIfChanged((DirectoryReader)indexReader);
            if(tr!=null) {
                //此时要记得把旧的索引Reader对象关闭
                indexReader.close();
                indexReader = tr;
            }
        }
        return indexReader;
    }
    
    /**
     * 获取IndexSearcher
     * @return
     * @throws Exception
     */
    public static IndexSearcher getIndexSearcher() throws Exception{
        return new IndexSearcher(getIndexReader());
    }
    
    /**
     * 根据查询条件,在控制台打印符合条件的n个结果
     * @param query
     * @param n
     * @throws Exception
     */
    public static void printTopDocsByQuery(Query query,int n) throws Exception{
        IndexSearcher indexSearcher = getIndexSearcher();
        // 搜索数据,两个参数:查询条件对象要查询的最大结果条数
        // 返回的结果是 按照匹配度排名得分前N名的文档信息(包含查询到的总条数信息、所有符合条件的文档的编号信息)
        TopDocs topDocs = indexSearcher.search(query, n);
        // 打印命中的总条数
        System.out.println("本次搜索共" + topDocs.totalHits + "条数据,最高分:"+topDocs.getMaxScore());
        
        // 获取得分文档对象(ScoreDoc)数组.SocreDoc中包含:文档的编号、文档的得分
        ScoreDoc[] scoreDocs = topDocs.scoreDocs;
        
        //循环
        for (ScoreDoc scoreDoc : scoreDocs) {
            // 取出文档编号
            int docID = scoreDoc.doc;
            System.out.println("=========文档的编号是:"+docID);
            // 取出文档得分
            System.out.println("当前文档得分: " + scoreDoc.score);
            // 根据编号去找文档
//            Document document = indexReader.document(docID);//方法1
            Document document = indexSearcher.doc(docID);//方法2
            //获取文档的所有字段对象
            List<IndexableField> fieldList= document.getFields();
            //遍历列表
            for (IndexableField field : fieldList) {
                //打印出所有的字段的名字和值(必须存储了的)
                System.out.println(field.name()+":"+field.stringValue());
            }
            
        }
    }
    public static void printTopDocsByQueryForHighlighter(Query query,int n) throws Exception{
        //=======高亮相关
        Formatter formatter=new SimpleHTMLFormatter("<em>","</em>");
        //得分对象
        Scorer scorer=new QueryScorer(query);
        //准备高亮工具
        Highlighter highlighter=new Highlighter(formatter, scorer);
        //=======搜索相关
        IndexSearcher indexSearcher = getIndexSearcher();
        // 搜索数据,两个参数:查询条件对象要查询的最大结果条数
        // 返回的结果是 按照匹配度排名得分前N名的文档信息(包含查询到的总条数信息、所有符合条件的文档的编号信息)
        TopDocs topDocs = indexSearcher.search(query, n);
        // 打印命中的总条数
        System.out.println("本次搜索共" + topDocs.totalHits + "条数据,最高分:"+topDocs.getMaxScore());
        
        // 获取得分文档对象(ScoreDoc)数组.SocreDoc中包含:文档的编号、文档的得分
        ScoreDoc[] scoreDocs = topDocs.scoreDocs;
        
        //循环
        for (ScoreDoc scoreDoc : scoreDocs) {
            // 取出文档编号
            int docID = scoreDoc.doc;
            System.out.println("=========文档的编号是:"+docID);
            // 取出文档得分
            System.out.println("当前文档得分: " + scoreDoc.score);
            // 根据编号去找文档
//            Document document = indexReader.document(docID);//方法1
            Document document = indexSearcher.doc(docID);//方法2
            //获取文档的所有字段对象
            List<IndexableField> fieldList= document.getFields();
            //遍历列表
            for (IndexableField field : fieldList) {
                String highlighterValue = highlighter.getBestFragment(analyzer, field.name(), field.stringValue());
                
                //打印出所有的字段的名字和值(必须存储了的)
                System.out.println(field.name()+":"+highlighterValue);
            }
            
        }
    }
    
    /**
     * 打印搜索结果文档
     * @param topDocs
     * @param indexSearcher
     * @throws Exception
     */
    public static void printTopDocs(TopDocs topDocs,IndexSearcher indexSearcher) throws Exception{
        // 打印命中的总条数
        System.out.println("本次搜索共" + topDocs.totalHits + "条数据,最高分:"+topDocs.getMaxScore());
        
        // 获取得分文档对象(ScoreDoc)数组.SocreDoc中包含:文档的编号、文档的得分
        ScoreDoc[] scoreDocs = topDocs.scoreDocs;
        
        //循环
        for (ScoreDoc scoreDoc : scoreDocs) {
            // 取出文档编号
            int docID = scoreDoc.doc;
            System.out.println("=========文档的编号是:"+docID);
            // 取出文档得分
            System.out.println("当前文档得分: " + scoreDoc.score);
            
            // 根据编号去找文档
//            Document document = indexReader.document(docID);//方法1
            Document document = indexSearcher.doc(docID);//方法2
            //获取文档的所有字段对象
            List<IndexableField> fieldList= document.getFields();
            //遍历列表
            for (IndexableField field : fieldList) {
                //打印出所有的字段的名字和值(必须存储了的)
                System.out.println(field.name()+":"+field.stringValue());
            }
            
        }
    }
    
}

猜你喜欢

转载自blog.csdn.net/weixin_42114097/article/details/81984727