zoukankan      html  css  js  c++  java
  • 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;
        }
    }
    人生没有彩排,每天都是现场直播!
  • 相关阅读:
    Android app 简单的电话拨号器
    JavaWEB开发中的/到底代表什么
    springmvc json
    ForeignKey.on_delete
    django 实现指定文件合并成压缩文件下载
    常用SQL的优化
    数据库 两个简单实用的表级优化方法
    一天只能触发一次操作
    Ajax 生成流文件下载 以及复选框的实现
    django Q和F查询
  • 原文地址:https://www.cnblogs.com/northern-light/p/10498358.html
Copyright © 2011-2022 走看看