Java集成Elasticsearch数据查询
Java集成Elasticsearch,进行索引数据查询,并进行sql权限过滤,指定id检索(in查询),多字段匹配检索,数据排序。由于权限过滤是根据sql语句判断当前用户或其部门可查询的数据,所以采用以下方法:
1.通过sql过滤出当前用户可查询的数据id集合idsList;
2.将当前用户可查询的数据id集合idsList通过QueryBuilders.idsQuery()进行查询,类似Mysql的in (’ ‘,’ ‘,’ ')查询。
Java代码
1.action代码
public void sq_list(){
//获取数据
PrintWriter writer = null;
//建立连接
RestHighLevelClient restHighLevelClient = RestHighLevelClientFactory.getHighLevelClient();
try {
writer = this.getResponse().getWriter();
//设置请求和响应相关参数
ResponseUtil.setResponseParam(this.getResponse(), this.getRequest());
//接收参数
Map<String,String> paramMap = RequestParamUtilOA.getParameterMap(this.getRequest());
String userId =this.getUserId();
paramMap.put("userId", userId);
String pageStr = paramMap.get("page");
String rowsStr = paramMap.get("rows");
int page = Integer.parseInt(pageStr);
int rows = Integer.parseInt(rowsStr);
paramMap.put("page", Integer.valueOf(page).toString());
paramMap.put("rows", Integer.valueOf(rows).toString());
String esSearch = paramMap.get("esSearch");
if (StringUtils.isNotBlank(esSearch)) {
Map<String, Object> searchMatchFw = indexTestService.searchMatchFw(AppParameters.index_name_fw, AppParameters.index_type_fw, paramMap, restHighLevelClient);
List<ZtxmOaFwSq> fwList = (List<ZtxmOaFwSq>)searchMatchFw.get("rows");
int total = Integer.valueOf(searchMatchFw.get("total").toString());
String resData = ztxmOaFwSqService.getZtxmOaFwSqPageJson(fwList, userId);
writer.write("{\"resCode\":\"10\",\"resMsg\":\"查询成功\",\"total\":" + total + ",\"rows\":" + resData + "}");
} else {
writer.write("{\"resCode\":\"10\",\"resMsg\":\"查询成功\",\"total\":0,\"rows\":[]}");
}
} catch (Exception e) {
e.printStackTrace();
writer.write("{\"resCode\":\"30\",\"resMsg\":\"查询失败\"}");
} finally {
//关闭连接
try {
restHighLevelClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
2.service代码
/**
* 全文检索
* @param index
* @param type
* @param paramMap
* @param rhclient
* @return
* @throws IOException
*/
public Map<String, Object> searchMatchFw(String index, String type, Map<String,String> paramMap, RestHighLevelClient rhclient) throws IOException;
3.serviceImpl代码
1.通过QueryBuilders.idsQuery()进行类似Mysql的in (’ ‘,’ ‘,’ ')查询
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(QueryBuilders.idsQuery().addIds(idsList.toArray(new String[]{})));
sourceBuilder.query(boolQueryBuilder);
2.索引多字段匹配数据查询
boolQueryBuilder.must(QueryBuilders.multiMatchQuery(esSearch, keySetArray).slop(0).type(“phrase”));
3.排序构建器:按照索引指定字段进行倒序排序
FieldSortBuilder sortBuilder = SortBuilders.fieldSort(“sqTjsj”).order(SortOrder.DESC);
sourceBuilder.sort(sortBuilder);
/**
* 全文检索
*/
@Override
public Map<String, Object> searchMatchFw(String index, String type, Map<String, String> paramMap, RestHighLevelClient rhclient) throws IOException {
Map<String, Object> map = new HashMap<String, Object>();
String esSearch = paramMap.get("esSearch");
String fullMath = paramMap.get("fullMath");
Integer page = null;
Integer rows = null;
String pageStr = paramMap.get("page");
String rowsStr = paramMap.get("rows");
if (StringUtils.isNotBlank(pageStr) && StringUtils.isNotBlank(rowsStr)) {
page = parseIntegerValue(pageStr, 1);
rows = parseIntegerValue(rowsStr, 1);
}
SearchRequest searchRequest = new SearchRequest(index);
searchRequest.types(type);
//搜索字段
Set<String> keySet = new HashSet<>();
String[] keySetArray = {};
// 获得字典组map对象
Map<String, Map<String, Map<String, String>>> dataDicGroupToItemMap = AmcInterface.getDataDicGroupToItemMap();
if (dataDicGroupToItemMap != null) {
// 获得字典组代码对应的全部字典项map对象
Map<String, Map<String, String>> zidianxMap = dataDicGroupToItemMap.get("AMC_OA_es_fw");
if (zidianxMap != null) {
keySet = zidianxMap.keySet();
keySetArray = keySet.toArray(new String[keySet.size()]);
/*if ("0".equals(fullMath)) {
sourceBuilder.query(QueryBuilders.multiMatchQuery(esSearch, keySetArray).slop(0).type("phrase"));
}else {
sourceBuilder.query(QueryBuilders.multiMatchQuery(esSearch, keySetArray));
}*/
}
}
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
//获取符合当前用户权限的发文id信息:通过sql过滤出当前用户可查询的数据id集合
List<String> idsList = getFwSqListIds(paramMap);
logger.info("列表查询:符合用户权限的id数量: "+idsList.size());
//查询参数设置
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
//将当前用户可查询的数据id集合通过QueryBuilders.idsQuery()进行in查询
if (idsList != null && idsList.size() > 0) {
boolQueryBuilder.must(QueryBuilders.idsQuery().addIds(idsList.toArray(new String[]{})));
}
//索引多字段匹配数据查询
if (keySetArray != null && keySetArray.length > 0) {
boolQueryBuilder.must(QueryBuilders.multiMatchQuery(esSearch, keySetArray).slop(0).type("phrase"));
}
sourceBuilder.query(boolQueryBuilder);
//排序构建器设置:按照索引数据的提交时间倒序排序
FieldSortBuilder sortBuilder = SortBuilders.fieldSort("sqTjsj").order(SortOrder.DESC);
sourceBuilder.sort(sortBuilder);
//基础参数设置
sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
sourceBuilder.size(5000);//默认查询10条数据
//设置高亮显示
HighlightBuilder highlightBuilder = new HighlightBuilder();
for(String key : keySet){
highlightBuilder.field(key);
}
highlightBuilder.requireFieldMatch(false);
highlightBuilder.preTags("<span style=\"color:red\">");
highlightBuilder.postTags("</span>");
sourceBuilder.highlighter(highlightBuilder);
//将请求体加入到请求中
searchRequest.source(sourceBuilder);
//发送请求
SearchResponse searchResponse = rhclient.search(searchRequest, RequestOptions.DEFAULT);
//处理搜索命中文档结果
SearchHits hits = searchResponse.getHits();
logger.info("es search total hits: " + hits.getTotalHits().value);
SearchHit[] searchHits = hits.getHits();
int total = 0;
List<ZtxmOaFwSq> ztxmOaFwSqList = new ArrayList<ZtxmOaFwSq>();
if (searchHits != null && searchHits.length > 0) {
//总条数
total = searchHits.length;
//分页信息
int begin = 0;
int sum = searchHits.length;
if (page != null && rows != null) {
if (page * rows <= searchHits.length) {
begin = (page - 1) * rows;
sum = begin + rows;
}else {
begin = (page - 1) * rows;
}
}
for (int i = begin; i < sum; i++) {
if (searchHits[i] != null) {
JSONObject jsonObject = JSONObject.parseObject(searchHits[i].getSourceAsString());
ZtxmOaFwSq ztxmOaFwSq = JSONObject.toJavaObject(jsonObject, ZtxmOaFwSq.class);
SearchHit hit = searchHits[i];
//logger.info("indexHit:" + hit.getIndex() + " typeHit:" + hit.getType() + " id:" + hit.getId() + " score" + hit.getScore());
// 搜索内容 -- 高亮
String content = "";
Map<String, HighlightField> highlightFields = hit.getHighlightFields();
if (keySet != null && keySet.size() > 0) {
for(String key : keySet){
HighlightField highlight = highlightFields.get(key);
if (highlight != null) {
Text[] fragments = highlight.fragments(); // 多值的字段会有多个值
if (fragments != null) {
for (int j = 0; j < fragments.length; j++) {
String fragmentString = fragments[j].string();
if (fragmentString != null) {
/*if (fragmentString.toString().length() > 50) {
content += fragmentString.toString().substring(0, 50) + "......";
} else {*/
content += fragmentString.toString();
/*}*/
}
content += "; ";
}
}
}
}
if (content != null) {
content.replace("\t", "");
content.replace("\n", "");
content.replace("\r", "");
}
//logger.info(content);
ztxmOaFwSq.setBak1(content);
}
ztxmOaFwSqList.add(ztxmOaFwSq);
}
}
}
map.put("rows", ztxmOaFwSqList);
map.put("total", total);
return map;
}