简介
从文档 Spring Data Elasticsearch - Reference Documentation 可以查看到Spring 与 Elasticsearch之间的版本关系。
这里由于项目的需要,我们选取的是 Neumann版本,对应的是
- Spring Data Elasticsearch 4.0.x
- Elasticsearch 7.6.2
- Spring Framework 5.2.12
- Spring Boot 2.3.x
官方文档 Spring Data Neumann goes GA,注意需要使用的是这个文档。
Elasticsearch 和 数据库 对比
SQL数据库 | Elasticsearch |
---|---|
column(列) | field(字段) |
row(行) | document(文档) |
table(表) | index(索引) |
schema(模式) | mapping(映射) |
database server(数据库服务器) | Elasticsearch 集群实例 |
测试方法
我们使用如下测试代码作为测试基础
package com.example.demo;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
public class ElasticsearchTests {
@Autowired
private ElasticsearchRestTemplate elasticsearchRestTemplate;
@Test
void testQuery() {
// 测试代码
}
}
只需要修改testQuery内代码,就可以完成针对不同代码的测试。
查询所有文档
查询一个索引中的所有数据。类似于查询语句
select * from metric_server;
接下来是获取Elasticsearch数据
@Data
class TestObject {
private String name;
private String region;
private String resourceId;
}
@Test
void testQuery() {
Query query = new NativeSearchQueryBuilder()
.withQuery(matchAllQuery())
.build();
IndexCoordinates indexCoordinates = IndexCoordinates.of("metric_server");
List<TestObject> objs = elasticsearchRestTemplate.queryForList(query, TestObject.class, indexCoordinates);
for ( int i = 0 ; i < objs.size() ;i++) {
System.out.println(objs.get(i));
}
}
根据条件简单查询
加上条件再做查询,类似于以下
select * from metric_server where name = 'agenttest';
代码也比较简单,使用termQuery来匹配
@Test
void testQuery() {
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name", "agenttest");
Query query = new NativeSearchQueryBuilder()
.withQuery(termQueryBuilder)
.build();
IndexCoordinates indexCoordinates = IndexCoordinates.of("metric_server");
List<TestObject> objs = elasticsearchRestTemplate.queryForList(query, TestObject.class, indexCoordinates);
for ( int i = 0 ; i < objs.size() ;i++) {
System.out.println(objs.get(i));
}
}
各匹配类型说明
Query类型 | 说明 |
---|---|
matchQuery | 分词,然后调用termQuery |
termQuery | 不分词,严格匹配 |
wildcardQuery | 通配符匹配 |
fuzzyQuery | 模糊匹配 |
rangeQuery | 范围匹配 |
booleanQuery | 布尔匹配(几个匹配之间做布尔运算) |
根据条件做复杂查询
做一个比较复杂的查询
select * from metric_server where name = 'agenttest' and timestamp > '2021-02-10 00:00:00'
同样的,我们可以使用下面代码做测试
@Test
void testQuery() {
long sinceTime = System.currentTimeMillis() - 1000L*60*60;;
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(termQuery("name", "agenttest"));
boolQueryBuilder.must(QueryBuilders.rangeQuery("timestamp").gte(sinceTime));
// boolQueryBuilder.filter(QueryBuilders.rangeQuery("timestamp").gte(sinceTime));
// 同上
Query query = new NativeSearchQueryBuilder()
.withQuery(boolQueryBuilder)
.build();
IndexCoordinates indexCoordinates = IndexCoordinates.of("metric_server");
List<TestObject> objs = elasticsearchRestTemplate.queryForList(query, TestObject.class, indexCoordinates);
for ( int i = 0 ; i < objs.size() ;i++) {
System.out.println(objs.get(i));
}
}
运行如下图
其中filter和must在这里是一致的,但是他们在ES里还是有差别的,详细参考
查询并排序
查询并测试
select * from metric_server where name = 'agenttest' order by timestamp desc;
使用下面代码测试
@Data
class TestObject {
private String name;
private String region;
private String resourceId;
private String timestamp;
}
@Test
void testQuery() {
TermQueryBuilder termQuery = QueryBuilders.termQuery("name", "agenttest");
SortBuilder sortBuilder = SortBuilders.fieldSort("timestamp").order(SortOrder.DESC);
Query query = new NativeSearchQueryBuilder()
.withQuery(termQuery)
.withSort(sortBuilder)
.build();
IndexCoordinates indexCoordinates = IndexCoordinates.of("metric_server");
List<TestObject> objs = elasticsearchRestTemplate.queryForList(query, TestObject.class, indexCoordinates);
System.out.println(objs.size());
for ( int i = 0 ; i < objs.size() ;i++) {
System.out.println(objs.get(i));
}
}
查看结果