Elasticsearch中的动态DSL解决方案

目录

问题背景

解决方案

编写es的mapper

动态dsl编写

使用mapper获取动态dsl

[远程调用restful api查询](#远程调用restful api查询)


问题背景

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

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

java 复制代码
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

java 复制代码
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 复制代码
<?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

java 复制代码
    @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的自动注入的

java 复制代码
@Autowired
private SqlSessionFactory sessionFactory;

远程调用restful api查询

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

相关推荐
超级阿飞1 小时前
利用Kubespray安装生产环境的k8s集群-实施篇
elasticsearch·容器·kubernetes
Ase5gqe6 小时前
大数据-259 离线数仓 - Griffin架构 修改配置 pom.xml sparkProperties 编译启动
xml·大数据·架构
史嘉庆6 小时前
Pandas 数据分析(二)【股票数据】
大数据·数据分析·pandas
唯余木叶下弦声7 小时前
PySpark之金融数据分析(Spark RDD、SQL练习题)
大数据·python·sql·数据分析·spark·pyspark
重生之Java再爱我一次8 小时前
Hadoop集群搭建
大数据·hadoop·分布式
豪越大豪10 小时前
2024年智慧消防一体化安全管控年度回顾与2025年预测
大数据·科技·运维开发
互联网资讯10 小时前
详解共享WiFi小程序怎么弄!
大数据·运维·网络·人工智能·小程序·生活
小诺大人11 小时前
Docker 安装 elk(elasticsearch、logstash、kibana)、ES安装ik分词器
elk·elasticsearch·docker
AI2AGI11 小时前
天天AI-20250121:全面解读 AI 实践课程:动手学大模型(含PDF课件)
大数据·人工智能·百度·ai·文心一言
贾贾202312 小时前
配电自动化中的进线监控技术
大数据·运维·网络·自动化·能源·制造·信息与通信