Elasticsearch SQL

Elasticsearch引擎

Elasticsearch是当今许多生产部署中使用最广泛的搜索引擎之一。 它基于Lucene搜索库,它提供的主要功能之一是在Lucene之上的基于JSON的查询DSL,它提供了一种易于使用的机制来与搜索引擎进行交互。 但是,查询DSL非常特定于Elasticsearch。 Elasticsearch 6.3中引入的SQL支持带来了一种针对搜索引擎运行查询的标准机制,并且朝着更容易被已熟悉SQL的开发人员采用更进一步。 尽管SQL最初是为与关系数据库管理系统一起使用而设计的,但是它已经在许多其他系统(例如NoSQL数据库)中实现。 以分布式数据处理引擎(如Apache Spark)或基于分布式缓存的计算系统(如Apache Ignite)中提供的受支持的SQL为例,其中SQL是所提供的核心查询工具之一。 在本文中,我们将探讨Elasticsearch SQL的工作方式。

初步设置

为了尝试本文中的示例,您需要启动一个本地Elasticsearch(至少6.3)实例。 在本文中,我们将使用最新的Elasticsearch 7.5。 我们将创建一个帖子索引,其中包含来自论坛的帖子。 我们将使用Elasticsearch Java客户端将数据馈入索引,并且我们将不为索引的字段提供显式映射(为简单起见,我们将让Elasticsearch为我们自动创建它)。 首先,我们将创建一个依赖于Elasticsearch Java高级客户端的Maven项目(不推荐使用旧的Elasticsearch HTTP客户端,并计划在Elasticsearch 8.0中将其删除):

 <dependency> 
     <groupId>org.elasticsearch.client< /groupId > 
     <artifactId>elasticsearch-rest-high-level-client< /artifactId > 
     <version>7.5.0< /version >  < /dependency > 

我们将使用以下代码在posts索引中创建10000个生成的post文档:

 RestHighLevelClient client = new RestHighLevelClient( 
                 RestClient.builder( 
                         new HttpHost( "localhost" , 9200 , "http" )));         
         String[] possibleUsers = new String[] { "Martin" , "Jim" , "John" }; 
         String[] possibleDates = new String[] { "2019-12-15" , "2019-12-16" , "2019-12-17" }; 
         String[] possibleMessages = new String[] { "Hello, Javaadvent !" , 
                 "Cool set of blog posts. We want more !" , 
                 "Elasticsearch SQL is great." };         
         for ( int i = 1 ; i <= 10000 ; i++) { 
             Map<String, Object> jsonMap = new HashMap<>(); 
             jsonMap.put( "user" , possibleUsers[ThreadLocalRandom.current().nextInt( 0 , 3 )]); 
             jsonMap.put( "date" , possibleDates[ThreadLocalRandom.current().nextInt( 0 , 3 )]); 
             jsonMap.put( "message" , possibleMessages[ThreadLocalRandom.current().nextInt( 0 , 3 )]); 
             IndexRequest request = new IndexRequest( "posts" ) 
                 .id(String.valueOf(i)).source(jsonMap); 
             client.index(request, RequestOptions.DEFAULT); 
         }         
         client.close(); 

运行SQL查询

我们可以使用Kibana来查询用户名为Martin的所有文档,如下所示:

 POST /_sql ? format =txt  { 
     "query" : "SELECT * FROM posts where user = 'Martin'"  } 

另一个示例是计算消息字段中包含Javaadvent单词的所有文档:

 POST /_sql ? format =txt  { 
     "query" : "SELECT count(*) FROM posts where message like '%Javaadvent%'"  } 

现在,如果您想在Java应用程序中运行上述查询,则有几种选择:

  • 使用Elasticsearch JDBC驱动程序运行它。 但是,此选项仅适用于白金级和企业级订阅。
  • REST客户端调用Elasticsearch SQL端点。 如果只有基本(免费)的Elasticsearch选项,则可以选择此选项。

您可以使用几乎所有用于Java的REST客户端来使用第二个选项,但是我们将使用低级Elasticsearch REST客户端:

 <dependency> 
     <groupId>org.elasticsearch.client< /groupId > 
     <artifactId>elasticsearch-rest-client< /artifactId > 
     <version>7.5.0< /version >  < /dependency > 

以下代码块仅从posts索引返回10个文档:

 RestClient restClient = RestClient.builder( 
                 new HttpHost( "localhost" , 9200 , "http" )).build();         
         Request request = new Request( "POST" , "/_sql" ); 
         request.setJsonEntity( "{\"query\":\"SELECT * FROM posts limit 10\"}" ); 
         Response response = restClient.performRequest(request); 
         String responseBody = EntityUtils.toString(response.getEntity()); 
         System.out.println(responseBody); 
         restClient.close(); 

要了解如何在后台执行SQL查询,可以使用/ _sql / translate端点下提供的translation API。 如果要查看为先前的SQL查询生成的查询DSL,我们可以在Kibana中运行以下命令:

 POST /_sql/translate  { 
     "query" : "SELECT * FROM posts limit 10" , 
     "fetch_size" : 10  } 

我们应该得到类似于以下内容的结果:

 { 
   "size" : 10, 
   "_source" : { 
     "includes" : [ 
       "message" , 
       "user" 
     ], 
     "excludes" : [ ] 
   }, 
   "docvalue_fields" : [ 
     { 
       "field" : "date" , 
       "format" : "epoch_millis" 
     } 
   ], 
   "sort" : [ 
     { 
       "_doc" : { 
         "order" : "asc" 
       } 
     } 
   ]  } 

Elasticsearch SQL功能

我们演示了如何执行基本的SQL查询。 Elasticsearch SQL引擎非常丰富,包括:

  • SQL查询响应的多种格式,例如csv,json,txt,yaml等;
  • 与Elasticsearch SQL一起应用其他查询DSL过滤;
  • elasticsearch-sql-cli实用程序提供的CLI,您可以在其中直接执行SQL查询。

关于SQL实现本身,可以参考支持的SQL命令以及SQL函数和运算符参考文档。

结论

在本文中,我们演示了如何使用Elasticsearch SQL与Elasticsearch引擎进行交互。 与基于JSON的查询DSL相比,使用此机制的可能性更高。 但是,Elasticsearch SQL不能替代它,而是在它之上构建的,并且可以满足搜索引擎提供的众多功能。

翻译自: https://www.javacodegeeks.com/2020/01/elasticsearch-sql.html

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用 Spring Boot 操作 Elasticsearch 7.6 进行 SQL 查询的示例代码: 1. 添加 ElasticsearchElasticsearch SQL 依赖库到 pom.xml 文件中: ```xml <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>elasticsearch-rest-client</artifactId> <version>7.6.0</version> </dependency> <dependency> <groupId>org.elasticsearch.plugin</groupId> <artifactId>x-pack-sql-jdbc</artifactId> <version>7.6.0</version> </dependency> ``` 2. 配置 Elasticsearch client: ```java @Configuration public class ElasticsearchConfig { @Value("${elasticsearch.host}") private String host; @Value("${elasticsearch.port}") private int port; @Bean public RestHighLevelClient client() { RestClientBuilder builder = RestClient.builder(new HttpHost(host, port, "http")); return new RestHighLevelClient(builder); } } ``` 3. 编写 SQL 查询代码: ```java @Service public class ElasticsearchService { @Autowired private RestHighLevelClient client; public void sqlQuery() throws IOException, SQLException { String sql = "SELECT * FROM my_index WHERE age > 30"; PreparedStatement statement = client.sql().prepareStatement(sql); ResultSet resultSet = statement.executeQuery(); while (resultSet.next()) { System.out.println(resultSet.getString("name") + " - " + resultSet.getInt("age")); } } } ``` 在上面的代码中,我们使用 `RestHighLevelClient` 对象调用 `sql()` 方法生成 `PreparedStatement` 对象,然后执行 SQL 查询并遍历结果集。 4. 在 application.properties 文件中配置 Elasticsearch 地址和端口号: ``` elasticsearch.host=localhost elasticsearch.port=9200 ``` 这样,我们就可以使用 Spring Boot 操作 Elasticsearch 7.6 进行 SQL 查询了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值