没有梦想,何必远方

lucene根据索引查询

package com.lucene.util;

import com.zxf.lucene.analyzer.lucene.IKAnalyzer;
import com.zxf.lucene.common.consts.SortType;
import com.zxf.lucene.dto.DocumentSearchDto;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.*;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.*;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;

import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.*;

/**
 * Created by jiangyang on 2019/3/8.
 */
public class LuceneQueryAndDeleteDemo {

    /**
     * 根据提交删除索引
     * @param fieldKey
     * @param value
     */
    public void deleteDocumentsByFieldKeyAndNumber(String fieldKey,long value){
        Query query = new DocValuesNumbersQuery(fieldKey,value);
        try {
            String dir = "索引文件存放路径";
            IndexWriter writer = getIndexWriterInstance(dir);
            writer.deleteDocuments(query);
            writer.commit();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 查询过程省略空null判断
     * @param dto
     * DocumentSearchDto中封装的查询条件
     *  查询条件 private BooleanQuery.Builder builder;
     *  需要查询的属性字段 private Set<String> keys;
     *  无序 正序 倒序 private Integer sortType;
     *  用户排序字段名称 private String sortFieldKey;
     *  用户排序的字段类型private SortField.Type sortFieldType;
     * @return
     */
    public List<Map> searchPageData(DocumentSearchDto dto){
        BooleanQuery.Builder builder = dto.getBuilder();
        Set<String> keys = dto.getKeys();
        if(builder == null || keys == null || keys.isEmpty()){
            return null;
        }
        Integer sortType = dto.getSortType();
        String sortTypeName = SortType.getName(sortType);
        String sortFieldKey = dto.getSortFieldKey();
        SortField.Type sortFieldType = dto.getSortFieldType();
        IndexReader reader = null;
        try {
            String dirPath = "索引文件存放位置";
            IndexWriter writer = getIndexWriterInstance(dirPath);
            Directory dir = writer.getDirectory();
            reader = DirectoryReader.open(dir);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        IndexSearcher indexSearcher = new IndexSearcher(reader);
        int total = 0;
        BooleanQuery query = builder.build();

        try {
            total = indexSearcher.count(query);
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
        if(total == 0){
            return  null;
        }
        int pageSize = dto.getPageSize();
        int totalPage = (int)Math.ceil(total*1.0/pageSize);

        int pageNum = dto.getPageNum();
        if( pageNum > totalPage ){
            return  null;
        }
        int topCount = pageNum*pageSize;
        TopDocs topDocs = null;
        //排序
        try {
            if(SortType.NOTORDER.code.equals(sortType)){
                topDocs = indexSearcher.search(query, topCount);
            }else if(SortType.NORMALORDER.code.equals(sortType)){
                topDocs = indexSearcher.search(query, topCount,new Sort(new SortField(sortFieldKey, sortFieldType, false)));
            }else{
                topDocs = indexSearcher.search(query, topCount,new Sort(new SortField(sortFieldKey,sortFieldType, true)));
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        //装配查询出的数据
        List<Document> docmentList = getDocmentList(topDocs, pageNum, pageSize, indexSearcher);
        List<Map> result = getResult(docmentList, keys, total);
        try {
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 多条件查询时,条件封装
     * @return
     */
    private BooleanQuery.Builder getQueryBuilder() {
        //必须满足此条件BooleanClause.Occur.MUST
        //必须不满足此条件BooleanClause.Occur.MUST_NOT
        //过滤BooleanClause.Occur.FILTER
        //或的关系BooleanClause.Occur.SHOULD
        String searchKey = "我叫张三,我是查询关键词";
        BooleanQuery.Builder builder = new BooleanQuery.Builder();
        //数值型的查询条件
        Query query = new DocValuesNumbersQuery("id", 123L);
        builder.add(query, BooleanClause.Occur.MUST);
        String dirPath = "索引文件存放路径";
        Analyzer analyzer =getIndexWriterInstance(dirPath).getAnalyzer();
        //保存的时候采用的什么分词器分词,查询的时候需要用同样的分词器将查询关键词分词后查询
        QueryParser parser = new QueryParser("name", analyzer);
        try {
            query = parser.parse(searchKey);
        } catch (ParseException e) {
           e.printStackTrace();
            return null;
        }
        builder.add(query, BooleanClause.Occur.MUST);
        //模糊查询 当对应字段字符串没有进行分词时,使用new WildcardQuery((new Term("name", "*张*")));
        Query sortNameQuery = new WildcardQuery((new Term("name", "*张*")));
        builder.add(sortNameQuery, BooleanClause.Occur.MUST);
        return builder;
    }

    /**
     * 获取Document数据集
     * @param topDocs
     * @param pageNum
     * @param pageSize
     * @param indexSearcher
     * @return
     */
    private List<Document> getDocmentList(TopDocs topDocs, int pageNum, int pageSize,IndexSearcher indexSearcher) {
        if(topDocs == null){
            return Collections.emptyList();
        }
        ScoreDoc[] scoreDocs = topDocs.scoreDocs;
        if(scoreDocs == null || scoreDocs.length == 0){
            return Collections.emptyList();
        }
        int total = scoreDocs.length;
        List<Document> documents = new ArrayList<>(pageSize);
        int start = (pageNum-1)*pageSize;
        for (int i=start;i<total;i++) {
            try {
                Document doc = indexSearcher.doc(scoreDocs[i].doc);
                documents.add(doc);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return documents;
    }

    private List<Map> getResult(List<Document> docmentList, Set<String> keys,int total) {
        if(docmentList == null || docmentList.isEmpty()){
            return null;
        }
        List list = new ArrayList();
        for(Document document:docmentList){
            Map map = new HashMap();
            for(String key:keys){
                map.put(key,document.get(key));
            }
            if(!map.isEmpty()){
                list.add(map);
            }
        }
       return list;
    }

    /**
     * @param dir 存放索引文件的 文件存放路径
     * @return
     */
    public  IndexWriter getIndexWriterInstance(String dir) {
        File file = new File(dir);
        if (!file.exists()) {
            file.mkdirs();
        }
        try{
            Directory directory = FSDirectory.open(Paths.get(dir));
            IKAnalyzer ikAnalyzer = new IKAnalyzer();
            //设置相应的分词器
            IndexWriterConfig indexWriterConfig = new IndexWriterConfig(ikAnalyzer);
            return new IndexWriter(directory, indexWriterConfig);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

 

posted @ 2019-03-08 21:25  北极丶光  阅读(585)  评论(0编辑  收藏  举报