SpringBoot 整合 ES 进行各种高级查询搜索

开发 项目管理
es 最大的亮点就是查询非常丰富,可以在上亿的数据里面快速搜索出目标数据,查询如果实现呢?

一、简介

在上篇​​ SpringBoot 整合 ElasticSearch​​​ 文章中,我们详细的介绍了 ElasticSearch 的索引和文档的基本增删改查的操作方法!

本文将重点介绍 ES 的各种高级查询写法和使用。

废话不多说,直接上代码!

二、代码实践

本文采用的SpringBoot版本号是2.1.0.RELEASE,服务端 es 的版本号是6.8.2,客户端采用的是官方推荐的Elastic Java High Level Rest Client版本号是6.4.2,方便与SpringBoot的版本兼容。

es 最大的亮点就是查询非常丰富,可以在上亿的数据里面快速搜索出目标数据,查询如果实现呢?请看下文:

  • 单条件精确查询
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {

@Autowired
private RestHighLevelClient client;

/**
* 单条件精确查询
* @throws IOException
*/
@Test
public void search0() throws IOException {
// 创建请求
SearchSourceBuilder builder = new SearchSourceBuilder()
.query(QueryBuilders.termsQuery("name", "赵里"));

//搜索
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("cs_index");
searchRequest.types("_doc");
searchRequest.source(builder);
// 执行请求
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
// 解析查询结果
System.out.println(response.toString());
}

}
  • 多条件精确查询,取并集
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {

@Autowired
private RestHighLevelClient client;

/**
* 多条件精确查询,取并集
* @throws IOException
*/
@Test
public void search1() throws IOException {
// 创建请求
SearchSourceBuilder builder = new SearchSourceBuilder()
.query(QueryBuilders.termsQuery("name", "张", "陈"));

//搜索
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("cs_index");
searchRequest.types("_doc");
searchRequest.source(builder);
// 执行请求
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
// 解析查询结果
System.out.println(response.toString());
}

}
  • 范围查询
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {

@Autowired
private RestHighLevelClient client;

/**
* 范围查询,包括from、to
* @throws IOException
*/
@Test
public void search2() throws IOException {
// 创建请求
SearchSourceBuilder builder = new SearchSourceBuilder()
.query(QueryBuilders.rangeQuery("age").from(20).to(32));

//搜索
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("cs_index");
searchRequest.types("_doc");
searchRequest.source(builder);
// 执行请求
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
// 解析查询结果
System.out.println(response.toString());
}


/**
* 范围查询,不包括from、to
* @throws IOException
*/
@Test
public void search3() throws IOException {
// 创建请求
SearchSourceBuilder builder = new SearchSourceBuilder()
.query(QueryBuilders.rangeQuery("age").from(20,false).to(30, false));

//搜索
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("cs_index");
searchRequest.types("_doc");
searchRequest.source(builder);
// 执行请求
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
// 解析查询结果
System.out.println(response.toString());
}


/**
* 范围查询, lt:小于,gt:大于
* @throws IOException
*/
@Test
public void search4() throws IOException {
// 创建请求
SearchSourceBuilder builder = new SearchSourceBuilder()
.query(QueryBuilders.rangeQuery("age").lt(30).gt(20));

//搜索
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("cs_index");
searchRequest.types("_doc");
searchRequest.source(builder);
// 执行请求
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
// 解析查询结果
System.out.println(response.toString());
}

}
  • 模糊查询,支持通配符
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {

@Autowired
private RestHighLevelClient client;

/**
* 模糊查询,支持通配符
* @throws IOException
*/
@Test
public void search5() throws IOException {
// 创建请求
SearchSourceBuilder builder = new SearchSourceBuilder()
.query(QueryBuilders.wildcardQuery("name","张三"));

//搜索
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("cs_index");
searchRequest.types("_doc");
searchRequest.source(builder);
// 执行请求
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
// 解析查询结果
System.out.println(response.toString());
}

}
  • 不使用通配符的模糊查询,左右匹配
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {

@Autowired
private RestHighLevelClient client;

/**
* 不使用通配符的模糊查询,左右匹配
* @throws IOException
*/
@Test
public void search6() throws IOException {
// 创建请求
SearchSourceBuilder builder = new SearchSourceBuilder()
.query(QueryBuilders.queryStringQuery("张三").field("name"));

//搜索
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("cs_index");
searchRequest.types("_doc");
searchRequest.source(builder);
// 执行请求
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
// 解析查询结果
System.out.println(response.toString());
}

}
  • 多字段模糊查询
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {

@Autowired
private RestHighLevelClient client;

/**
* 多字段模糊查询
* @throws IOException
*/
@Test
public void search7() throws IOException {
// 创建请求
SearchSourceBuilder builder = new SearchSourceBuilder()
.query(QueryBuilders.multiMatchQuery("长", "name", "city"));

//搜索
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("cs_index");
searchRequest.types("_doc");
searchRequest.source(builder);
// 执行请求
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
// 解析查询结果
System.out.println(response.toString());
}

}
  • 多字段模糊查询
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {

@Autowired
private RestHighLevelClient client;

/**
* 分页搜索
* @throws IOException
*/
@Test
public void search8() throws IOException {
// 创建请求
SearchSourceBuilder builder = new SearchSourceBuilder()
.from(0).size(2);

//搜索
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("cs_index");
searchRequest.types("_doc");
searchRequest.source(builder);
// 执行请求
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
// 解析查询结果
System.out.println(response.toString());
}

}
  • 字段排序
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {

@Autowired
private RestHighLevelClient client;

/**
* 排序,字段的类型必须是:integer、double、long或者keyword
* @throws IOException
*/
@Test
public void search9() throws IOException {
// 创建请求
SearchSourceBuilder builder = new SearchSourceBuilder()
.sort("createTime", SortOrder.ASC);

//搜索
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("cs_index");
searchRequest.types("_doc");
searchRequest.source(builder);
// 执行请求
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
// 解析查询结果
System.out.println(response.toString());
}

}
  • 精确统计筛选文档数
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {

@Autowired
private RestHighLevelClient client;

/**
* 精确统计筛选文档数,查询性能有所降低
* @throws IOException
*/
@Test
public void search10() throws IOException {
// 创建请求
SearchSourceBuilder builder = new SearchSourceBuilder()
.trackTotalHits(true);

//搜索
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("cs_index");
searchRequest.types("_doc");
searchRequest.source(builder);
// 执行请求
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
// 解析查询结果
System.out.println(response.toString());
}

}
  • 设置源字段过滤返回
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {

@Autowired
private RestHighLevelClient client;

/**
* 设置源字段过虑,第一个参数结果集包括哪些字段,第二个参数表示结果集不包括哪些字段
* @throws IOException
*/
@Test
public void search11() throws IOException {
// 创建请求
SearchSourceBuilder builder = new SearchSourceBuilder()
.fetchSource(new String[]{"name","age","city","createTime"},new String[]{});

//搜索
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("cs_index");
searchRequest.types("_doc");
searchRequest.source(builder);
// 执行请求
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
// 解析查询结果
System.out.println(response.toString());
}

}
  • 根据 id 精确匹配
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {

@Autowired
private RestHighLevelClient client;

/**
* 根据id精确匹配
* @throws IOException
*/
@Test
public void search12() throws IOException {
String[] ids = new String[]{"1","2"};
// 创建请求
SearchSourceBuilder builder = new SearchSourceBuilder()
.query(QueryBuilders.termsQuery("_id", ids));

//搜索
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("cs_index");
searchRequest.types("_doc");
searchRequest.source(builder);
// 执行请求
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
// 解析查询结果
System.out.println(response.toString());
}

}
  • matchAllQuery 搜索全部
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {

@Autowired
private RestHighLevelClient client;

/**
* matchAllQuery搜索全部
* @throws IOException
*/
@Test
public void search21() throws IOException {
// 创建请求
SearchSourceBuilder builder = new SearchSourceBuilder()
.query(QueryBuilders.matchAllQuery());

//搜索
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("cs_index");
searchRequest.types("_doc");
searchRequest.source(builder);
// 执行请求
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
// 解析查询结果
System.out.println(response.toString());
}
}
  • match 搜索匹配
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {

@Autowired
private RestHighLevelClient client;

/**
* match搜索匹配
* @throws IOException
*/
@Test
public void search22() throws IOException {
// 创建请求
SearchSourceBuilder builder = new SearchSourceBuilder()
.query(QueryBuilders.matchQuery("name", "张王"));

//搜索
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("cs_index");
searchRequest.types("_doc");
searchRequest.source(builder);
// 执行请求
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
// 解析查询结果
System.out.println(response.toString());
}
}
  • bool组合查询
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {

@Autowired
private RestHighLevelClient client;

/**
* bool组合查询
* @throws IOException
*/
@Test
public void search23() throws IOException {
// 创建请求
SearchSourceBuilder builder = new SearchSourceBuilder();

BoolQueryBuilder boolQueryBuilder=new BoolQueryBuilder();
boolQueryBuilder.must(QueryBuilders.matchQuery("name", "张王"));
boolQueryBuilder.must(QueryBuilders.rangeQuery("age").lte(30).gte(20));
builder.query(boolQueryBuilder);

//搜索
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("cs_index");
searchRequest.types("_doc");
searchRequest.source(builder);
// 执行请求
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
// 解析查询结果
System.out.println(response.toString());
}
}
  • nested 类型嵌套查询
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {

@Autowired
private RestHighLevelClient client;

/**
* nested类型嵌套查询
* @throws IOException
*/
@Test
public void search24() throws IOException {
// 创建请求
SearchSourceBuilder builder = new SearchSourceBuilder();

//条件查询
BoolQueryBuilder mainBool=new BoolQueryBuilder();
mainBool.must(QueryBuilders.matchQuery("name", "赵六"));

//nested类型嵌套查询
BoolQueryBuilder boolQueryBuilder=new BoolQueryBuilder();
boolQueryBuilder.must(QueryBuilders.matchQuery("products.brand", "A"));
boolQueryBuilder.must(QueryBuilders.matchQuery("products.title", "巧克力"));
NestedQueryBuilder nested = QueryBuilders.nestedQuery("products",boolQueryBuilder, ScoreMode.None);
mainBool.must(nested);

builder.query(mainBool);

//搜索
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("cs_index");
searchRequest.types("_doc");
searchRequest.source(builder);
// 执行请求
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
// 解析查询结果
System.out.println(response.toString());
}
}
  • 多条件查询 + 排序 + 分页
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {

@Autowired
private RestHighLevelClient client;

/**
* 多条件查询 + 排序 + 分页
* @throws IOException
*/
@Test
public void search29() throws IOException {
// 创建请求
SearchSourceBuilder builder = new SearchSourceBuilder();

//条件搜索
BoolQueryBuilder boolQueryBuilder=new BoolQueryBuilder();
boolQueryBuilder.must(QueryBuilders.matchQuery("name", "张王"));
boolQueryBuilder.must(QueryBuilders.rangeQuery("age").lte(30).gte(20));
builder.query(boolQueryBuilder);

//结果集合分页
builder.from(0).size(2);

//排序
builder.sort("createTime",SortOrder.ASC);

//搜索
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("cs_index");
searchRequest.types("_doc");
searchRequest.source(builder);
// 执行请求
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
// 解析查询结果
System.out.println(response.toString());
}
}
  • 聚合查询-求和
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {

@Autowired
private RestHighLevelClient client;

/**
* 聚合查询 sum
* @throws IOException
*/
@Test
public void search30() throws IOException {
// 创建请求
SearchSourceBuilder builder = new SearchSourceBuilder();

//条件搜索
builder.query(QueryBuilders.matchAllQuery());
//聚合查询
AggregationBuilder aggregation = AggregationBuilders.sum("sum_age").field("age");
builder.aggregation(aggregation);

//搜索
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("cs_index");
searchRequest.types("_doc");
searchRequest.source(builder);
// 执行请求
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
// 解析查询结果
System.out.println(response.toString());
}
}
  • 聚合查询-求平均值
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {

@Autowired
private RestHighLevelClient client;

/**
* 聚合查询 avg
* @throws IOException
*/
@Test
public void search31() throws IOException {
// 创建请求
SearchSourceBuilder builder = new SearchSourceBuilder();

//条件搜索
builder.query(QueryBuilders.matchAllQuery());
//聚合查询
AggregationBuilder aggregation = AggregationBuilders.avg("avg_age").field("age");
builder.aggregation(aggregation);

//搜索
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("cs_index");
searchRequest.types("_doc");
searchRequest.source(builder);
// 执行请求
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
// 解析查询结果
System.out.println(response.toString());
}
}
  • 聚合查询-计数
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {

@Autowired
private RestHighLevelClient client;

/**
* 聚合查询 count
* @throws IOException
*/
@Test
public void search32() throws IOException {
// 创建请求
SearchSourceBuilder builder = new SearchSourceBuilder();

//条件搜索
builder.query(QueryBuilders.matchAllQuery());
//聚合查询
AggregationBuilder aggregation = AggregationBuilders.count("count_age").field("age");
builder.aggregation(aggregation);

//搜索
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("cs_index");
searchRequest.types("_doc");
searchRequest.source(builder);
// 执行请求
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
// 解析查询结果
System.out.println(response.toString());
}
}
  • 聚合查询-分组
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {

@Autowired
private RestHighLevelClient client;

/**
* 聚合查询 分组
* @throws IOException
*/
@Test
public void search33() throws IOException {
// 创建请求
SearchSourceBuilder builder = new SearchSourceBuilder();

//条件搜索
builder.query(QueryBuilders.matchAllQuery());
//聚合查询
AggregationBuilder aggregation = AggregationBuilders.terms("tag_createTime").field("createTime")
.subAggregation(AggregationBuilders.count("count_age").field("age")) //计数
.subAggregation(AggregationBuilders.sum("sum_age").field("age")) //求和
.subAggregation(AggregationBuilders.avg("avg_age").field("age")); //求平均值

builder.aggregation(aggregation);

//不输出原始数据
builder.size(0);

//搜索
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("cs_index");
searchRequest.types("_doc");
searchRequest.source(builder);
// 执行请求
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
// 解析查询结果
System.out.println(response.toString());
}
}

三、小结

本文主要围绕 SpringBoot 整合 ElasticSearch 进行各种高级查询的介绍,在下篇文章中,我们会重点介绍 es 的性能调优!

责任编辑:武晓燕 来源: Java极客技术
相关推荐

2023-09-01 07:31:24

2022-05-30 07:31:38

SpringBoot搜索技巧

2023-11-06 12:00:04

GORM

2023-08-09 08:01:00

WebSockett服务器web

2021-04-07 08:43:09

SpringBootRocketMQ开发技术

2024-11-14 10:38:43

2011-08-01 11:56:45

Google搜索

2022-07-12 07:33:47

ES类似连表查询

2020-04-23 15:08:41

SpringBootMyCatJava

2020-01-10 15:42:13

SpringBootRedis数据库

2021-07-16 07:57:35

SpringBootOpenFeign微服务

2022-04-28 07:31:41

Springkafka数据量

2020-06-29 07:43:12

缓存RedisSpringBoot

2021-05-19 09:53:16

SpringbootMyBatisMySQL

2023-07-05 09:48:44

Activiti部署

2021-04-15 09:17:01

SpringBootRocketMQ

2009-12-25 13:41:33

2011-06-19 11:03:30

搜索引擎SERP

2024-05-24 11:38:17

SymPy计算运算

2024-09-02 09:14:36

SpringRabbitMQ数据
点赞
收藏

51CTO技术栈公众号