当前位置: 首页 > article >正文

Elasticsearch中的动态DSL解决方案

目录

问题背景

解决方案

编写es的mapper

动态dsl编写

使用mapper获取动态dsl

远程调用restful api查询


问题背景

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

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

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

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

答案是可行的

解决方案

编写es的mapper

package com.tml.mouseDemo.mapper;

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

@Mapper
public interface ESMapper {


    String queryOrderById(@Param("name") String name, @Param("id") String id);
}

动态dsl编写

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.tml.mouseDemo.mapper.ESMapper">


    <select id="queryOrderById" resultType="string">
    {
    "query":{
        "bool":[
            "term":{
                "id":"${id}"
            }

        <if test="name!=null">
            ,
            "term":{
            "name":"${name}"
            }
        </if>
        ]
        }
    }
    </select>
</mapper>

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

使用mapper获取动态dsl

    @Test
    public void testEs() {
       
        Map<String, String> map = new HashMap<>();
        map.put("name", "tml");
        map.put("id", "hello world");
        BoundSql bSql = sessionFactory.getConfiguration().getMappedStatement("queryOrderById").getBoundSql(map);

        log.info("bSql:{}", bSql.getSql());
}

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

@Autowired
private SqlSessionFactory sessionFactory;

远程调用restful api查询

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


http://www.kler.cn/news/233132.html

相关文章:

  • Android 自定义BaseActivity
  • ES实战-book笔记1
  • OCP使用web console创建和构建应用
  • .gitlab-ci.yml文件参数
  • 极狐GitLab 与钉钉的集成实践
  • C++的学习记录
  • [office] excel求乘积的公式和方法 #媒体#笔记#经验分享
  • H12-821_74
  • 贵金属交易包括哪些?香港有哪些贵金属交易平台?
  • 力扣热题100_双指针_11_盛最多水的容器
  • 2022美国大学生数学建模(优秀获奖论文)-A题:Power Planning Model: Magic Weapon for Cyclists
  • Linux time命令教程:如何测量命令的执行时间(附案例详解和注意事项)
  • 【PyQt】08 - 编辑Tab顺序
  • 编译器选择:VSCode安装MarkDown插件
  • mysql RR、RC隔离级别实现原理
  • Node.js之npm单独与批量升级依赖包的方式
  • Android14音频进阶:MediaPlayerService如何启动AudioTrack 上篇(五十五)
  • 有关网络安全的课程学习网页
  • Nginx全面配置
  • 【Java EE初阶十】多线程进阶二(CAS等)
  • 从0开始图形学(光栅化)
  • 【Python】使用 requirements.txt 与 pytorch 相关配置
  • 写读后感的时候,可以适当地引用书中的内容吗?
  • 54.螺旋矩阵(Java)
  • 【JS逆向三】逆向某某网站的sign参数,并模拟生成仅供学习
  • 利用Pybind11封装Python版的WiringPi!
  • 【QT+QGIS跨平台编译】之三十:【NetCDF+Qt跨平台编译】(一套代码、一套框架,跨平台编译)
  • 用HTML5实现灯笼效果
  • 文心一言 VS 讯飞星火 VS chatgpt (198)-- 算法导论14.3 6题
  • shell脚本之无限计时器