lucene 4.4 Java 简单 Demo

本文介绍了一个基于Lucene的索引与搜索系统实现,包括如何构建索引、使用多字段查询解析器进行搜索、高亮显示及排序等功能。通过具体代码示例展示了整个流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/**
 *
 */
package com.ccp.lucene;

import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import javax.annotation.Resource;

import jxl.write.DateTime;

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.queryparser.classic.MultiFieldQueryParser;
import org.apache.lucene.queryparser.classic.ParseException;
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.highlight.Highlighter;
import org.apache.lucene.search.highlight.InvalidTokenOffsetsException;
import org.apache.lucene.search.highlight.QueryScorer;
import org.apache.lucene.search.highlight.SimpleHTMLFormatter;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.store.Directory;
import org.apache.lucene.util.Version;
import org.springframework.context.ApplicationContext;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.stereotype.Service;
import org.wltea.analyzer.lucene.IKAnalyzer;

import com.aliyun.common.utils.DateUtil;
import com.ccp.ServiceFactory;
import com.ccp.core.entity.goods.Goods;
import com.ccp.util.CustomBeanFactory;
import com.ccp.util.PageBean;

import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.document.*;


/**
 * @author Dylan Wang
 *
 * 09/05/2014
 *
 * this class is using for creating index or searching
 *
 */
 

public class LuceneFactory {
    
    private static String currentIndex;
    
//    @Resource
//    private ServiceFactory s;
    
    @Resource
    public ServiceFactory s;
    
    public LuceneFactory()
    {    
        
    }
    

    public void init() {

        Properties properties;
        try {
            properties = PropertiesLoaderUtils
            .loadAllProperties("luceneIndex.properties");
            
            String indexA = properties.getProperty("LuceneIndexA");
            String indexB = properties.getProperty("LuceneIndexB");
            
            currentIndex = indexA;
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    
    public void index(List<Goods> goods) throws IOException
    {
        System.out.println("开始创建索引文件……");
        IKAnalyzer analyzer= new IKAnalyzer();
        IndexWriterConfig indexWriterConfig= new IndexWriterConfig(Version.LUCENE_44,analyzer);        
        IndexWriter indexWriter = null;
        try {
            Directory directory = FSDirectory.open(new File(currentIndex));
            
            //创建 IndexWriter
            indexWriter= new IndexWriter(directory,indexWriterConfig);
            System.out.println("开始创建索引文档信息……");
            
            //创建索引文件
            addDocument(indexWriter,goods);                        
            
            System.out.println("索引文件创建完成!");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            System.out.println("索引文件创建失败!");
        }
        finally
        {            
            //优化索引并关闭Writer
            if(indexWriter!=null)
                indexWriter.close();
        }
        
        
    }
    
    //创建索引文件,
    private void addDocument(IndexWriter writer, List<Goods> goods) throws IOException {
        for (Goods good : goods) {
            Document document= new Document();
            
            document.add(new Field("ID",good.getId().toString(),Field.Store.YES,Field.Index.NO));
            
            document.add(new Field("title",good.getTitle(),Field.Store.YES,Field.Index.ANALYZED));
            
            document.add(new Field("createTime",good.getId().toString(),Field.Store.YES,Field.Index.NO));
            
            document.add(new Field("SalesNum", s.orderService.querySales(good.getId()).toString(), Field.Store.YES, Field.Index.NO));
            
            document.add(new Field("PageViewNum", "100", Field.Store.YES, Field.Index.NO));
            writer.addDocument(document);
        }
    }
    
    /**
     * 构造排序字段
     * @param sortParm 排序字段 (1-createTime  2-SalesNum  3-PageViewNum)
     * @return
     */
    private String getSortField(int sortParm) {
        String sortField="";
        
        //构造排序字段
        switch (sortParm) {
        case 2:
            sortField = "SalesNum";
            break;
        case 3:
            sortField = "PageViewNum";
            break;
        case 1:
        default:
            sortField = "createTime";
            break;
        }
        return sortField;
    }
    
    /**
     * 获取排序方式,True-降序  False-升序
     * @param sortType 排序方式 (1-升序 2-降序)
     * @return
     */
    private boolean getSortType(int sortType) {
        
        boolean isDesc =true;
        
        switch (sortType) {
        case 1:
            isDesc =false;
            break;
        case 2:
        default:
            isDesc=true;
            break;
        }
        return isDesc;
    }
    
    /**
     *
     * @param keyWord    搜索关键字
     * @param pageBean    分页数据
     * @param sortParm    排序字段 (1-createTime  2-SalesNum  3-PageViewNum)
     * @param sortType  排序方式 (1-升序 2-降序)
     * @return
     * @throws IOException
     * @throws ParseException
     * @throws InvalidTokenOffsetsException
     */
    public List<Goods> search(String keyWord,PageBean pageBean,int sortParm,int sortType) throws IOException, ParseException, InvalidTokenOffsetsException {
        
        String sortField = getSortField(sortParm);
        
        boolean isDesc = getSortType(sortType);
        
        List<Goods> goodsList= new ArrayList<Goods>();
        
        File file = new File(currentIndex);
        
        IndexReader reader = DirectoryReader.open(FSDirectory.open(file));
        
        IndexSearcher searcher = new IndexSearcher(reader);
        
        IKAnalyzer analyzer = new IKAnalyzer();
        
        MultiFieldQueryParser fieldQueryParser = new MultiFieldQueryParser(Version.LUCENE_44, new String[]{"title"},analyzer);
        
        Query query= fieldQueryParser.parse(keyWord);
        
        TopDocs resultDocs = searcher.search(query, pageBean.getPageNumber() * pageBean.getPageSize(),new Sort(new SortField(sortField,SortField.Type.DOC ,isDesc)));
        
        System.out.println("第一次查询总条数:" + resultDocs.totalHits);
        System.out.println("第一次查询总条数:" + resultDocs.scoreDocs.length);
        
        ScoreDoc scoreDoc = null;
        
        //返回上页最后一条数据的编号
        int lastPageDocNumber = (pageBean.getPageNumber() -1) * pageBean.getPageSize();
        if(lastPageDocNumber>0)
        {
            scoreDoc = resultDocs.scoreDocs[lastPageDocNumber -1];
        }
        if(scoreDoc!=null)
            System.out.println("上一页的最后一条为:"+ searcher.doc(scoreDoc.doc).get("ID"));
        
        //查询结果集,并按照指定字段排序,排序按照文档排序,非积分
        TopDocs topDocs= searcher.searchAfter(scoreDoc, query, pageBean.getPageSize(), new Sort(new SortField(sortField,SortField.Type.DOC ,isDesc)));
        
        System.out.println("第二次查询总条数:" + topDocs.totalHits);
        System.out.println("第二次查询总条数:" + topDocs.scoreDocs.length);
        
        //设置总条数
        pageBean.setTotalDatas(topDocs.totalHits);
                
        //设置高亮
        SimpleHTMLFormatter simpleHTMLFormatter = new SimpleHTMLFormatter("<font color='red'>", "</font>");
        Highlighter highlighter = new Highlighter(simpleHTMLFormatter, new QueryScorer(query));
        
        Goods goods;
        for (ScoreDoc item : topDocs.scoreDocs) {
            Document document = searcher.doc(item.doc);
            goods = new Goods();
            
            goods.setId(Integer.parseInt(document.get("ID")));
            
            //高亮“Title”列
            String title = document.get("title");
            TokenStream tokenStream = analyzer.tokenStream("title", new StringReader(title));            
            goods.setTitle(highlighter.getBestFragment(tokenStream, title));        
                        
            goods.setCreateTime(com.ccp.util.DateUtil.dateFormat(document.get("createTime")));
            
            goods.setSalesNum(Integer.parseInt(document.get("SalesNum")));
            goods.setPageViewNum(Integer.parseInt(document.get("PageViewNum")));
            
            goodsList.add(goods);
        }        
        
        return goodsList;
    }
    
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值