在开发项目中通过使用Solr所提供的Solrj(java客户端)获取索引库中的数据,这才是真正对项目起实质性作用的功能,提升平台的检索性能及检索结果的精确性
第一步,引入相关依赖的jar包
第二步,根据solrj所提供的各种查询场景实现对应的功能,直接上代码,该代码是项目中实际使用场景而编写的,主要都是根据solr查询规范实现
private ReturnDTO handleData(SearchArgumentsDTO searchArgumentsDTO) { ReturnDTO returnDTO = new ReturnDTO(); String keywords = searchArgumentsDTO.getKeywords(); String[] fields = searchArgumentsDTO.getFields(); String[] fieldVals = searchArgumentsDTO.getFieldVals(); int currentPage = searchArgumentsDTO.getCurrentPage(); int pageSize = searchArgumentsDTO.getPageSize(); String[] sortfields = searchArgumentsDTO.getSortfields(); String[] sortTypes = searchArgumentsDTO.getSortTypes(); boolean hightlight = searchArgumentsDTO.getHightlight(); String[] orField = searchArgumentsDTO.getOrField(); List<String[]> orFieldVals = searchArgumentsDTO.getOrFieldVals(); String[] offField = searchArgumentsDTO.getOffField(); List<String[]> offFieldVals = searchArgumentsDTO.getOffFieldVals(); String[] rangeField = searchArgumentsDTO.getRangeField(); List<String[]> rangeFieldVals = searchArgumentsDTO.getRangeFieldVals(); boolean facetFlag = searchArgumentsDTO.getFacetFlag(); String[] facetFields = searchArgumentsDTO.getFacetFields(); String collection = searchArgumentsDTO.getCollection(); if(StringUtils.isNull(collection)) collection = "CIPBook"; SolrServerClient solrServerClient = SolrServerClient.getInstance(); HttpSolrServer solrServer = solrServerClient.getServer(collection); Page page = new Page(); if(solrServer==null){ returnDTO.setResult(page); returnDTO.setStatus(StatusConsts.STATUS_PARAMETER_ERROR); returnDTO.setReturnMsg(StatusConsts.STATUS_PARAMETER_ERROR_MESSAGE); return returnDTO; } // 检测输入是否合法 int fieldsLength = fields.length; int fieldValsLength = fieldVals.length; int sortfieldsLength = sortfields.length; int sortTypesLength = sortTypes.length; if ((fieldsLength != fieldValsLength)||(sortfieldsLength != sortTypesLength)) { returnDTO.setResult(page); returnDTO.setStatus(StatusConsts.STATUS_PARAMETER_ERROR); returnDTO.setReturnMsg(StatusConsts.STATUS_PARAMETER_ERROR_MESSAGE); return returnDTO; } SolrQuery query = null; String highlightFieldStr = ""; List<SolrSearchBookDTO> beans = null; StringBuffer baseQuery = new StringBuffer(); baseQuery.append("*:*"); String[] mainKey = new String[]{"bibName","author","subjectTerm","pubName","isbn"}; if (StringUtils.isNotNull(keywords)) { baseQuery.delete(0,baseQuery.length()); baseQuery.append("("); for (String string : mainKey) { baseQuery.append(string + ":" + keywords); baseQuery.append(" OR "); } baseQuery.delete(baseQuery.length()-4, baseQuery.length()); baseQuery.append(")"); // baseQuery.append("keywords:" + keywords); } // bibGid:(5265074 OR 4886655) if (StringUtils.isNotNull(orField[0]) && StringUtils.isNotNull(orFieldVals.get(0)[0])) { // baseQuery.delete(0,baseQuery.length()); for (int i=0;i<orField.length;i++) { baseQuery.append(" AND "); baseQuery.append(orField[i] +":("); for (String orFieldVal : orFieldVals.get(i)) { baseQuery.append(orFieldVal).append(" OR "); } baseQuery.delete(baseQuery.length()-4, baseQuery.length()); baseQuery.append(")"); } } // keywords:(* NOT 少儿 NOT 教材),注意*不要忘记写 if (StringUtils.isNotNull(offField[0]) && StringUtils.isNotNull(offFieldVals.get(0)[0]) && offField.length==offFieldVals.size()) { for (int i=0;i<offField.length;i++) { baseQuery.append(" AND "); baseQuery.append(offField[i]+":(* NOT "); for (String offFieldVal : offFieldVals.get(i)) { baseQuery.append(offFieldVal).append(" NOT "); } baseQuery.delete(baseQuery.length()-5, baseQuery.length()); baseQuery.append(")"); } } // pubTime:[2012-04 TO 2016-01] 中括号包含查询范围,大括号则不包含 if (StringUtils.isNotNull(rangeField[0]) && StringUtils.isNotNull(rangeFieldVals.get(0)[0]) && rangeField.length==rangeFieldVals.size()) { for (int i=0;i<rangeField.length;i++) { baseQuery.append(" AND "); baseQuery.append(rangeField[i]+":[ "+rangeFieldVals.get(i)[0]+" TO "+rangeFieldVals.get(i)[1]+"]"); // baseQuery.delete(baseQuery.length()-5, baseQuery.length()); // baseQuery.append(")"); } } if (fieldsLength > 0&&StringUtils.isNotNull(fields[0])){ baseQuery.append(" AND "); for (int i = 0; i < fieldsLength; i++) { // query.addFilterQuery(fields[i] + ":" + fieldVals[i]); baseQuery.append(fields[i]+":").append(fieldVals[i]); baseQuery.append(" AND "); } baseQuery.delete(baseQuery.length()-5, baseQuery.length()); } try { // 初始化查询对象 query = new SolrQuery(baseQuery.toString()); // 设置起始位置与返回结果数 currentPage = currentPage == 0 ? 1 : currentPage; pageSize = pageSize == 0 ? 10 : pageSize; query.setStart((currentPage - 1) * pageSize); query.setRows(pageSize); // 设置排序 if (sortfieldsLength > 0&&StringUtils.isNotNull(sortfields[0])) for (int i = 0; i < sortfieldsLength; i++) { if ("asc".equalsIgnoreCase(sortTypes[i])) { query.addSort(sortfields[i], SolrQuery.ORDER.asc); } else { query.addSort(sortfields[i], SolrQuery.ORDER.desc); } } // 设置高亮 if (hightlight) { highlightFieldStr = "bibName,author,isbn,pubName";// 多个用逗号隔开 query.setHighlight(true); // 开启高亮组件 query.addHighlightField(highlightFieldStr);// 高亮字段 query.setHighlightSimplePre("<font color="red">");// 标记 query.setHighlightSimplePost("</font>"); query.setHighlightSnippets(1);// 结果分片数,默认为1 query.setHighlightFragsize(1000);// 每个分片的最大长度,默认为100 } //分组查询条件 if(facetFlag && StringUtils.isNotNull(facetFields[0])){ query.setFacet(true); query.addFacetField(facetFields);//设置需要facet的字段 query.setFacetLimit(10);//限制facet返回的数量 } } catch (Exception e) { e.printStackTrace(); } QueryResponse response = null; try { response = solrServer.query(query); beans = response.getBeans(SolrSearchBookDTO.class); long numFound = response.getResults().getNumFound(); page.setTotalRecord((int)numFound); page.setCurrentPage(currentPage); if (hightlight) updateHighlightFields(highlightFieldStr, beans, response); if(facetFlag && StringUtils.isNotNull(facetFields[0])){ List<SolrSearchFacetDTO> facetList = new ArrayList<SolrSearchFacetDTO>(); List<FacetField> facets = response.getFacetFields();//返回的facet列表 for (FacetField facet : facets) { SolrSearchFacetDTO solrSearchFacetDTO = new SolrSearchFacetDTO(); String facetField = facet.getName(); solrSearchFacetDTO.setFacetField(facetField); List<Count> counts = facet.getValues(); List<FacetCountDTO> facetCount = new ArrayList<FacetCountDTO>(); for (Count count : counts) { FacetCountDTO facetCountDTO = new FacetCountDTO(); facetCountDTO.setFacetFieldVal(count.getName()); facetCountDTO.setFacetCount(count.getCount()+""); facetCount.add(facetCountDTO); } if("pubYear".equals(facetField)){ Collections.sort(facetCount, new Comparator<FacetCountDTO>() { public int compare(FacetCountDTO obj1, FacetCountDTO obj2) { return obj2.getFacetFieldVal().compareTo(obj1.getFacetFieldVal()); } }); } solrSearchFacetDTO.setFacetCount(facetCount); facetList.add(solrSearchFacetDTO); } Map<String,Object> resvalMap = new HashMap<String,Object>(); List<Object> resvalList = new ArrayList<Object>(); resvalMap.put("beans", beans); resvalMap.put("facet", facetList); resvalList.add(resvalMap); page.setData(resvalList); }else{ page.setData(beans); } page.setPageSize(pageSize); int totalPage = (int) ((numFound + pageSize - 1) / pageSize); page.setTotalPage(totalPage); returnDTO.setResult(page); returnDTO.setStatus(StatusConsts.STATUS_SUCCESS); returnDTO.setReturnMsg(StatusConsts.STATUS_SUCCESS_MESSAGE); } catch (Exception e) { e.printStackTrace(); returnDTO.setResult(page); returnDTO.setStatus(StatusConsts.STATUS_FAILURE); returnDTO.setReturnMsg(StatusConsts.STATUS_FAILURE_MESSAGE); return returnDTO; } return returnDTO; } private void updateHighlightFields(String highlightFieldStr, List<SolrSearchBookDTO> beans, QueryResponse response) throws IntrospectionException, IllegalAccessException, InvocationTargetException { Map<String, Map<String, List<String>>> highlighting = response .getHighlighting(); String[] highlightFieldArr = highlightFieldStr.split(","); for (SolrSearchBookDTO searchBook : beans) { String key = searchBook.getBibGid(); Map<String, List<String>> map = highlighting.get(key); if (map == null) continue; for (String highlightField : highlightFieldArr) { if (map.get(highlightField) == null) continue; String highlightFieldVal = map.get(highlightField).get(0); PropertyDescriptor propertyDescriptor = new PropertyDescriptor( highlightField, SolrSearchBookDTO.class); Method writeMethod = propertyDescriptor.getWriteMethod(); writeMethod.invoke(searchBook, highlightFieldVal); } } }
其中最核心的代码就是以下代码,根据所拼接好的查询条件字符串实现查询并封装成项目中自定义好的类对象
同时自定义类的属性上需添加solrj中所提供的注解,才能将从索引库中查询的数据进行映射