Java查询Elasticsearch数据根据指定id检索(in查询)、sql权限过滤、多字段匹配检索及数据排序

 更新时间:2024年05月21日 09:24:58   作者:cjewioivsxoewll  
在Java开发中Elasticsearch(简称ES)是一个非常流行的搜索引擎,它提供了强大的全文搜索和分析功能,这篇文章主要给大家介绍了关于Java查询Elasticsearch数据根据指定id检索(in查询)、sql权限过滤、多字段匹配检索及数据排序的相关资料,需要的朋友可以参考下

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

附:复杂查询示例

一旦我们建立了与Elasticsearch集群的连接,就可以使用Java来执行复杂的查询操作了。以下是一个示例,展示如何使用Java对ES中的数据进行查询:

import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.elasticsearch.client.RequestOptions;

public class ElasticsearchQuery {
    private ElasticsearchClient elasticsearchClient;

    public ElasticsearchQuery() {
        elasticsearchClient = new ElasticsearchClient();
    }

    public SearchResponse executeQuery() throws IOException {
        RestHighLevelClient client = elasticsearchClient.getClient();

        SearchRequest searchRequest = new SearchRequest("my_index");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        searchSourceBuilder.query(QueryBuilders.matchQuery("title", "java"))
            .sort(SortBuilders.fieldSort("date").order(SortOrder.DESC))
            .from(0).size(10);

        searchRequest.source(searchSourceBuilder);

        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);

        return searchResponse;
    }
}

在以上示例中,我们首先创建了一个SearchRequest对象,并指定要查询的索引名称(“my_index”)。然后,我们创建了一个SearchSourceBuilder对象,并设置了查询条件、排序方式以及结果集的分页信息。最后,我们通过RestHighLevelClient对象执行查询请求,并返回查询结果。

总结 

到此这篇关于Java查询Elasticsearch数据根据指定id检索(in查询)、sql权限过滤、多字段匹配检索及数据排序的文章就介绍到这了,更多相关Java集成es数据查询内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • SpringBoot thymeleaf实现饼状图与柱形图流程介绍

    SpringBoot thymeleaf实现饼状图与柱形图流程介绍

    这篇文章主要介绍了SpringBoot thymeleaf实现饼状图与柱形图流程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2022-12-12
  • mybatis一级缓存和二级缓存的区别及说明

    mybatis一级缓存和二级缓存的区别及说明

    这篇文章主要介绍了mybatis一级缓存和二级缓存的区别及说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-11-11
  • Java中获取类路径classpath的简单方法(推荐)

    Java中获取类路径classpath的简单方法(推荐)

    下面小编就为大家带来一篇Java中获取类路径classpath的简单方法(推荐)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-09-09
  • Java多线程下载的实现方法

    Java多线程下载的实现方法

    复习多线程的时候,练习了下,顺便记录一下:
    2013-03-03
  • Elasticsearch外部词库文件更新及使用

    Elasticsearch外部词库文件更新及使用

    这篇文章主要为大家介绍了Elasticsearch外部词库文件更新及使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-11-11
  • Intellj idea新建的java源文件夹不是蓝色的图文解决办法

    Intellj idea新建的java源文件夹不是蓝色的图文解决办法

    idea打开java项目后新建的模块中,java文件夹需要变成蓝色,这篇文章主要给大家介绍了关于Intellj idea新建的java源文件夹不是蓝色的相关资料,文中通过图文介绍的非常详细,需要的朋友可以参考下
    2024-02-02
  • Java 死锁解决方案顺序锁和轮询锁

    Java 死锁解决方案顺序锁和轮询锁

    这篇文章主要介绍了Java 死锁解决方案顺序锁和轮询锁,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-05-05
  • Java继承Thread类创建线程类示例

    Java继承Thread类创建线程类示例

    这篇文章主要介绍了Java继承Thread类创建线程类,结合实例形式分析了java线程操作相关使用技巧与注意事项,需要的朋友可以参考下
    2019-09-09
  • 基于Java开发实现ATM系统

    基于Java开发实现ATM系统

    这篇文章主要为大家详细介绍了基于Java开发实现ATM系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-08-08
  • struts2中simple主题下<s:fieldError>标签默认样式的移除方法

    struts2中simple主题下<s:fieldError>标签默认样式的移除方法

    这篇文章主要给大家介绍了关于struts2中simple主题下<s:fieldError>标签默认样式的移除方法,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴,下面随着小编来一起学习学习吧
    2018-10-10

最新评论