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;
    }
}
相關文章
相關標籤/搜索