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; } }