SQL还能操作ES?

131 阅读3分钟

首先需要引入POM

<dependency>
  <groupId>org.elasticsearch.plugin</groupId>
  <artifactId>x-pack-sql-jdbc</artifactId>
  //注意版本号
  <version>8.6.1</version>
</dependency>

引入POM时候要注意版本号,必须和你的ES服务器的版本号要对应,否则后端一启动服务就报错

image.png

main方法测试

String esAddress = "ES的IP地址";

String address = "jdbc:es://" + esAddress;
Properties properties = new Properties();
properties.put("user", "ES的账号");
properties.put("password", "ES的密码");

//这里使用的语法糖开关连接,不太了解语法糖的请参考其他文章
try (Connection connection = DriverManager.getConnection(address, properties);
     Statement statement = connection.createStatement();
) {
    //这一步是输出连接对象,查看是否连接成功
    System.out.println(statement);

    String sql = "SELECT docId FROM person limit 1";

    ResultSet results = statement.executeQuery(sql);
    //如果有数据就获取
    while (results.next()) {
        //docId 对应ES里的key
        String name = results.getString("docId");
        System.out.println(name);
    }
} catch (Exception e) {
    e.printStackTrace();
}

kibana对应main方法里的操作

1 原语句

GET /索引名/_search
{
}

结果:

image.png

2 SQL方式的语句

方式一:
GET /_sql
{
  "query": "SELECT docId FROM 索引名 limit 1 "  
}

方式二:
GET /_sql
{
  "query": """
  SELECT docId FROM "索引名" limit 1
  """
}

方式三:把结果转为文档类型
GET /_sql?format=txt
{
  "query": "SELECT docId FROM 索引名 limit 1 "  
}


方式一和二的结果:

image.png

方式三的结果:

image.png

启动服务后使用mybatis操作

1 pom

   <dependency>
   //这个类如果在上一步测试里引入了就不用在引入,这里我引入的版本是7.10.0
            <groupId>org.elasticsearch.plugin</groupId>
            <artifactId>x-pack-sql-jdbc</artifactId>
            <version>7.10.0</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>


        <!--elasticsearch相关依赖-->
<!--        <dependency>-->
<!--            <groupId>org.springframework.boot</groupId>-->
<!--            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>-->
<!--        </dependency>-->

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.2</version>
        </dependency>

如果只用SQL操作ES可以不用引入spring-boot-starter-data-elasticsearch的包,这个包是对应使用API方式调用ES,如果需要使用可自行在引入。

2 yml配置

spring:
  datasource:
    username: ES账号
    password: ES密码
    ## 数据库驱动类
    driver-class-name: org.elasticsearch.xpack.sql.jdbc.EsDriver
    url: jdbc:es://ES的URL
    ## 切换自定义数据源 这里使用druid 数据源,相关依赖自己引入
    type: com.alibaba.druid.pool.DruidDataSource

3 po对象

@Data
public class PersonPO implements Serializable {

    private String traceId;
}

4 mapper接口

@Mapper
public interface MytestiMapper extends BaseMapper<PersonPO> {
    PersonPO selectDemo();
}

5 mapper.xml 这个文件自己去resources目录下创建

  • 注意:索引最好用双引号包起来,否则如果有些索引是以时间区分的话,会报索引查找错误。
  • 例如:索引是 person-2023-02-05
<select id="selectDemo" resultType="com.shou.es.po.PersonPO">
    SELECT traceId FROM "person-2023-02-05"   limit 1

</select>

6 启动服务测试

@Autowired
PersonMapper PersonMapper;


@GetMapping("/")
public String demo() {

    PersonPO one =  PersonPOMapper.selectDemo();
    System.out.println(one.getTraceId());

    return "1";
}

控制台输出的结果

image.png

总结:

  • 1 对于ES语法不是很好的老铁,可以使用SQL调用的方式去获取ES数据,相对容易很多。主要的关键在于这个包x-pack-sql-jdbc,他会把你的SQL语句转为ES语句去查询。
  • 2 但是就算使用SQL获取,对于一些高级操作是不支持的,例如:子查询,连接查询,因为ES本身也不支持这样的操作,详情可以看官网
  • 3 如果有错误的地方,麻烦路过的老铁指点下,谢谢

官网地址

最后附带一句:

在生产环境中不建议x-pack-sql-jdbc来操作ES,以下是原因:

  1. 性能差:需要将SQL查询转换为ES的原生DSL进行查询,这额外的转换操作会造成一定的性能损失。

  2. 功能有限:只支持ES的一个子集功能,比如不支持buckets聚合(换成SQL,就是不支持 group 这些函数)等,功能相比ES DSL来说非常有限。

  3. 排查困难:SQL查询抽象了底层ES查询,不利于分析和调优查询性能。

  4. 说了这么多,感觉好像什么都没说!!!!

image.png