当前位置:   article > 正文

Elasticsearch中的动态DSL解决方案_elasticsearch dsl 动态拼装

elasticsearch dsl 动态拼装

目录

问题背景

解决方案

编写es的mapper

动态dsl编写

使用mapper获取动态dsl

远程调用restful api查询


问题背景

在大数据量的业务系统中,一般都会引入Elasticsearch来作为搜索引擎,而搜索的条件又是多种多样的。回顾下,如果是mysql等这种关系型数据库来作为存储介质呢?我们是不是可以通过mybatis的动态sql解析功能就能轻轻松松的搞定。

或许你也许会问,es不是提供了java版本的sdk么,通过sdk可以动态的构建dsl语句的,确实如此,不过这样的可读性远远没有将dsl放在xml中,可以看下在java代码中操作es的代码案例

  1. public static void main(String[] args) throws IOException {
  2. // 初始化RestHighLevelClient
  3. RestClientBuilder builder = RestClient.builder(new HttpHost("localhost", 9200, "http"));
  4. RestHighLevelClient client = new RestHighLevelClient(builder);
  5. // 创建查询条件
  6. SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
  7. searchSourceBuilder.query(QueryBuilders.matchQuery("fieldname", "value")); // 动态查询字段名和值
  8. // 创建搜索请求
  9. SearchRequest searchRequest = new SearchRequest("indexname"); // 指定索引名
  10. searchRequest.source(searchSourceBuilder);
  11. // 执行搜索
  12. SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
  13. // 处理搜索结果
  14. SearchHits hits = searchResponse.getHits();
  15. for (SearchHit hit : hits) {
  16. System.out.println(hit.getSourceAsString());
  17. }
  18. // 关闭客户端
  19. client.close();
  20. }

mybatis的执行流程中,就是通过SqlSessionFactory创建SqlSession,有了SqlSession可以开始执行sql,执行sql的时候,会将动态的sql转成一个MappedStatement,通过这个可以创建BoundSql,我们是不是可以利用mybatis执行mysql的一部分功能,拿到BoundSql,然后通过http的方式直接远程调用es查询?

答案是可行的

解决方案

编写es的mapper

  1. package com.tml.mouseDemo.mapper;
  2. import org.apache.ibatis.annotations.Mapper;
  3. import org.apache.ibatis.annotations.Param;
  4. @Mapper
  5. public interface ESMapper {
  6. String queryOrderById(@Param("name") String name, @Param("id") String id);
  7. }

动态dsl编写

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  3. <mapper namespace="com.tml.mouseDemo.mapper.ESMapper">
  4. <select id="queryOrderById" resultType="string">
  5. {
  6. "query":{
  7. "bool":[
  8. "term":{
  9. "id":"${id}"
  10. }
  11. <if test="name!=null">
  12. ,
  13. "term":{
  14. "name":"${name}"
  15. }
  16. </if>
  17. ]
  18. }
  19. }
  20. </select>
  21. </mapper>

dsl的语法就不多介绍了,在这个xml文件中,可以使用mybatis的<if> <when> <choose> <foreach>等诸多标签,通过这些个标签的组合,你可以编写多条件检索的复杂dsl

使用mapper获取动态dsl

  1. @Test
  2. public void testEs() {
  3. Map<String, String> map = new HashMap<>();
  4. map.put("name", "tml");
  5. map.put("id", "hello world");
  6. BoundSql bSql = sessionFactory.getConfiguration().getMappedStatement("queryOrderById").getBoundSql(map);
  7. log.info("bSql:{}", bSql.getSql());
  8. }

其中,sessionFactory是通过spring的自动注入的

  1. @Autowired
  2. private SqlSessionFactory sessionFactory;

远程调用restful api查询

拿到dsl以后,就可以通过http远程调用restful api拿到结果了,通过httpClient或者是RestTemplate实现都行,这里就不赘述了。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/204276
推荐阅读
相关标签
  

闽ICP备14008679号