Elasticsearch SQL ORM查询案例

bboss ES SQL是针对es jdbc的替代解决方案

the best elasticsearch highlevel java rest api——-bboss

bboss 提供一组sql和fetchQuery API,可替代官方es jdbc模块;采用bboss即可拥有bboss的客户端自动发现和容灾能力、对es、jdk、spring boot的兼容性能力,又可以拥有es jdbc的所有功能,同时还解决了因为引入es jdbc导致项目对es版本的强依赖和兼容性问题,参考demo:

orm查询

分页查询
https://gitee.com/bboss/eshelloword-booter/blob/master/src/test/java/org/bboss/elasticsearchtest/sql/SQLPagineTest.java

目前官方es sql提供的功能有限,也可以在bboss中使用插件提供的功能,下面有专门的章节介绍。

本文详细说明上面的案例:

1 orm查询

实体定义说明:

通过column指定索引文档和对象属性的映射关系,指定日期格式和时区信息,示例如下:

  1. private String docInfoAuthor;

@Column(name=”docInfo.author”,dataformat = “yyyy-MM-dd’T’HHss.SSS’Z’”,timezone = “Etc/UTC”,locale = “zh”)

以rest sql api为例来介绍es 6.3.0的sql orm查询功能

  1. package org.bboss.elasticsearchtest.sql;
  2. import org.frameworkset.elasticsearch.ElasticSearchHelper;
  3. import org.frameworkset.elasticsearch.client.ClientInterface;
  4. import org.frameworkset.elasticsearch.entity.sql.SQLRestResponse;
  5. import org.frameworkset.elasticsearch.entity.sql.SQLRestResponseHandler;
  6. import org.junit.Test;
  7. import java.util.HashMap;
  8. import java.util.List;
  9. import java.util.Map;
  10. /**
  11. * 以rest sql api为例来介绍es 6.3.0的sql orm查询功能
  12. */
  13. public class SQLOrmTest {
  14. /**
  15. * 代码中的sql检索,返回Map类型集合,亦可以返回自定义的对象集合
  16. */
  17. @Test
  18. public void testDemoQuery(){
  19. ClientInterface clientUtil = ElasticSearchHelper.getRestClientUtil();
  20. List<Map> json = clientUtil.sql(Map.class,"{\"query\": \"SELECT * FROM demo\"}");
  21. System.out.println(json);
  22. }
  23. /**
  24. * 代码中的sql检索,返回Map类型集合,亦可以返回自定义的对象集合
  25. */
  26. @Test
  27. public void testMapQuery(){
  28. ClientInterface clientUtil = ElasticSearchHelper.getRestClientUtil();
  29. List<Map> json = clientUtil.sql(Map.class,"{\"query\": \"SELECT * FROM dbclobdemo\"}");
  30. System.out.println(json);
  31. }
  32. /**
  33. * 配置文件中的sql dsl检索,返回Map类型集合,亦可以返回自定义的对象集合
  34. */
  35. @Test
  36. public void testMapSQLQueryFromDSL(){
  37. ClientInterface clientUtil = ElasticSearchHelper.getConfigRestClientUtil("esmapper/sql.xml");//初始化一个加载sql配置文件的es客户端接口
  38. //设置sql查询的参数
  39. Map params = new HashMap();
  40. params.put("channelId",1);
  41. List<Map> json = clientUtil.sql(Map.class,"sqlQuery",params);
  42. System.out.println(json);
  43. }
  44. /**
  45. * 代码中的sql检索,返回Map类型对象,亦可以返回自定义的对象
  46. */
  47. public void testMapObjectQuery(){
  48. ClientInterface clientUtil = ElasticSearchHelper.getRestClientUtil();
  49. Map json = clientUtil.sqlObject(Map.class,"{\"query\": \"SELECT * FROM dbclobdemo\"}");
  50. System.out.println(json);
  51. }
  52. * 配置文件中的sql dsl检索,返回Map类型对象,亦可以返回自定义的对象
  53. */
  54. @Test
  55. public void testMapObjectSQLQueryFromDSL(){
  56. ClientInterface clientUtil = ElasticSearchHelper.getConfigRestClientUtil("esmapper/sql.xml");//初始化一个加载sql配置文件的es客户端接口
  57. //设置sql查询的参数
  58. Map params = new HashMap();
  59. params.put("channelId",1);
  60. Map json = clientUtil.sqlObject(Map.class,"sqlQuery",params);
  61. System.out.println(json);
  62. }
  63. /**
  64. * 代码中的sql检索,返回DocObject 类型集合
  65. */
  66. @Test
  67. public void testObjectListQuery(){
  68. ClientInterface clientUtil = ElasticSearchHelper.getRestClientUtil();
  69. List<DocObject> json = clientUtil.sql(DocObject.class,"{\"query\": \"SELECT * FROM dbclobdemo\"}");
  70. System.out.println(json);
  71. }
  72. /**
  73. * 配置文件中的sql dsl检索,返回DocObject 类型集合
  74. */
  75. @Test
  76. public void testObjectSQLQueryFromDSL(){
  77. ClientInterface clientUtil = ElasticSearchHelper.getConfigRestClientUtil("esmapper/sql.xml");//初始化一个加载sql配置文件的es客户端接口
  78. //设置sql查询的参数
  79. Map params = new HashMap();
  80. params.put("channelId",1);
  81. List<DocObject> json = clientUtil.sql(DocObject.class,"sqlQuery",params);
  82. System.out.println(json);
  83. }
  84. /**
  85. * 代码中的sql检索,返回DocObject 类型对象
  86. */
  87. @Test
  88. public void testObjectQuery(){
  89. ClientInterface clientUtil = ElasticSearchHelper.getRestClientUtil();
  90. DocObject json = clientUtil.sqlObject(DocObject.class,"{\"query\": \"SELECT * FROM dbclobdemo where documentId = 1\"}");
  91. System.out.println(json);
  92. }
  93. /**
  94. * 配置文件中的sql dsl检索,返回DocObject 类型对象
  95. */
  96. @Test
  97. public void testConditionObjectSQLQueryFromDSL(){
  98. ClientInterface clientUtil = ElasticSearchHelper.getConfigRestClientUtil("esmapper/sql.xml");//初始化一个加载sql配置文件的es客户端接口
  99. //设置sql查询的参数
  100. Map params = new HashMap();
  101. params.put("channelId",1);
  102. DocObject json = clientUtil.sqlObject(DocObject.class,"sqlQuery",params);
  103. System.out.println(json);
  104. }
  105. * sql转换为dsl
  106. */
  107. @Test
  108. public void testTranslate(){
  109. String json = clientUtil.executeHttp("/_xpack/sql/translate",
  110. "{\"query\": \"SELECT * FROM dbclobdemo limit 5\",\"fetch_size\": 5}",
  111. ClientInterface.HTTP_POST
  112. );
  113. System.out.println(json);
  114. }
  115. /**
  116. * 低阶的检索方法
  117. */
  118. @Test
  119. public void testSQLRestResponse(){
  120. ClientInterface clientUtil = ElasticSearchHelper.getRestClientUtil();
  121. SQLRestResponse sqlRestResponse = clientUtil.executeHttp("/_xpack/sql",
  122. "{\"query\": \"SELECT * FROM dbclobdemo where documentId = 1\"}",
  123. ClientInterface.HTTP_POST,
  124. new SQLRestResponseHandler());
  125. System.out.println(sqlRestResponse);
  126. }
  127. }

每个orm查询方法的都有对应的功能注释说明,可以根据需要使用相关的方法。

代码中用到的sql dsl脚本配置文件及内容:esmapper/sql.xml

我们将配置文件放到工程resources目录下面即可。sql配置说明:

sql中特定的字符串参数语法

  1. {"query": "SELECT * FROM dbclobdemo where channelId=#[channelId] and docTitle='#[channelId,quoted=false]'"}

我们使用#[xxx]类型变量传递sql参数时,如果是字符串内容会自动在值的两边带上双引号,但是在sql语句是字符串值是用单引号’来标识的,所以通过qutoed=false来指示解析引擎不要在值的两边加双引号,然后在外部手动添加单引号:

‘#[channelId,quoted=false]’

如果sql语句比较长,可能要换行,es暂时不支持多行sql语句的执行,bboss通过下面特定的语法,来包围多行sql,sql解析引擎在第一次解析sql的时候讲其中的多行sql解析为一行:

“””

例如:

  1. {
  2. ## 指示sql语句中的回车换行符会被替换掉开始符,注意dsl注释不能放到sql语句中,否则会有问题,因为sql中的回车换行符会被去掉,导致回车换行符后面的语句变道与注释一行
  3. ## 导致dsl模板解析的时候部分sql段会被去掉
  4. "query": #"""
  5. SELECT * FROM dbclobdemo
  6. where channelId=#[channelId]
  7. """,
  8. ## 指示sql语句中的回车换行符会被替换掉结束符
  9. "fetch_size": #[fetchSize]
  10. }

2 Elasticsearch-sql查询

基于第三方Elasticsearch-sql插件的查询功能的使用方法和bboss提供的查询api使用方法一致,只是检索的rest服务换成/_sql服务即可:

  1. /**
  2. * Elasticsearch-SQL插件功能测试方法
  3. */
  4. public void testESSQL(){
  5. ClientInterface clientUtil = ElasticSearchHelper.getRestClientUtil();
  6. ESDatas<Map> esDatas = //ESDatas包含当前检索的记录集合,最多10条记录,由sql中的limit属性指定
  7. clientUtil.searchList("/_sql",//sql请求
  8. "select * from vem_order_index_2018 limit 0,10", //elasticsearch-sql支持的sql语句
  9. Map.class);//返回的文档封装对象类型
  10. //获取结果对象列表
  11. List<Map> demos = esDatas.getDatas();
  12. //获取总记录数
  13. long totalSize = esDatas.getTotalSize();
  14. System.out.println(totalSize);
  15. }

Elasticsearch-SQL插件sql转dsl功能:

  1. /**
  2. * Elasticsearch-SQL插件功能:sql转dsl
  3. */
  4. @Test
  5. public void testESSQLTranslate(){
  6. ClientInterface clientUtil = ElasticSearchHelper.getRestClientUtil();
  7. String dsl = //将sql转换为dsl
  8. clientUtil.executeHttp("/_sql/_explain",//sql转dsl请求
  9. "select operModule.keyword from dbdemo group by operModule.keyword ",ClientInterface.HTTP_POST);//返回的转换的结果
  10. //获取总记录数
  11. }

官方的ES-SQL功能目前还不成熟,必须Elasticsearch 6.3以上的版本,而且收费;Elasticsearch-SQL插件功能全,免费,可以在不同的Elasticsearch版本上运行。

3 开发交流

elasticsearch技术交流:166471282

elasticsearch: