章节
第一章链接: SpringBoot集成Elasticsearch7.x(1)|(增删改查功能实现)
第二章链接: SpringBoot集成Elasticsearch7.x(2)|(复杂查询)
第三章链接: SpringBoot集成Elasticsearch7.x(3)|(aggregations之指标聚合查询)
第四章链接: SpringBoot集成Elasticsearch7.x(4)|(aggregations之分桶聚合查询)
第五章链接: SpringBoot集成Elasticsearch7.x(5)|(term、match、match_phrase区别)
第六章链接: SpringBoot集成Elasticsearch8.x(6)|(新版本Java API Client使用)
第七章链接: SpringBoot集成Elasticsearch8.x(7)|(新版本Java API Client使用完整示例)
本章节主要介绍SpringBoot项目集成ElasticSearch的一些相关知识,包括集成版本、依赖、集成方式、以及增删改查的使用。查看需要对Springboot项目有一定的了解。本文将采用官方推荐使用的Java High Level REST Client方式实现ElasticSearch操作。
Elasticsearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java语言开发的,并作为Apache许可条款下的开放源码发布,是一种流行的企业级搜索引擎。
Elasticsearch 是面向文档型数据库,一条数据在这里就是一个文档。我们将 Elasticsearch 里存储文档数据和关系型数据库 MySQL 存储数据的概念进行一个类比如下图
pom依赖如下,主要列出SpringBoot依赖版本以及ElasticSearch版本,其他需要依赖自行添加(本文使用的具体版本为elasticsearch-rest-high-level-client-7.12.1.jar)
<!-- Springboot 版本 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.7</version>
<relativePath/>
</parent>
<!-- ElasticSearch依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
yml配置ES对应参数
es:
port: 9200
servers: localhost
config配置,此处为单机配置,集群模式再次基础上修改也行
@Configuration
public class RestClientConfig extends AbstractElasticsearchConfiguration {
@Value("${es.clusterName}")
private String clusterName;
@Value("${es.servers}")
private String servers;
@Value("${es.port}")
private int port;
@Override
@Bean
public RestHighLevelClient elasticsearchClient() {
final ClientConfiguration clientConfiguration = ClientConfiguration.builder()
.connectedTo(servers + ":" + port)
.build();
return RestClients.create(clientConfiguration).rest();
}
}
定义数据类型,类似于mysql的表,定义好字段,该处用了lombok表达式,如不需要可自定义set、get方法取代 @Field()可以定义字段的类型以及分词等。
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
//@Document(indexName = "es_architecture")
public class ArchitectureDto {
@ApiModelProperty(value = "id", required = true)
@Id
private String id;
@ApiModelProperty(value = "建筑名称", required = true)
@Field(type = FieldType.Text,analyzer = "ik-max-word")
private String name;
@ApiModelProperty(value = "所在省份", required = true)
@Field(type = FieldType.Text)
private String province;
@ApiModelProperty(value = "所在城市", required = true)
@Field(type = FieldType.Text)
private String city;
@ApiModelProperty(value = "所在区", required = true)
@Field(type = FieldType.Text)
private String area;
@ApiModelProperty(value = "详细街道地址", required = true)
@Field(type = FieldType.Text)
private String address;
@ApiModelProperty(value = "经纬度", required = true)
private LocationPo location;
@ApiModelProperty(value = "描述", required = true)
@Field(type = FieldType.Text)
private String description;
@ApiModelProperty(value = "评分", required = true)
@Field(type = FieldType.Double)
private double score;
@ApiModelProperty(value = "门票价格", required = true)
@Field(type = FieldType.Double)
private double price;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public class LocationPo {
@ApiModelProperty(value = "经度", required = true)
private double lon;
@ApiModelProperty(value = "纬度", required = true)
private double lat;
}
通过restHighLevelClient对象对ElasticSearch数据库进行操作,restHighLevelClient由springboot容器创建管理,用户不需要进行配置,使用的时候注入即可,本次使用的是测试类代码编写方式。
@RunWith(SpringRunner.class)
@SpringBootTest(classes = EsApplication.class)
public class EsHandTest {
@Autowired
private RestHighLevelClient restHighLevelClient;
// 测试文档的添加
@Test
public void testCreateDoc() throws IOException {
//CreateDoc5()创建实体方法,可自己实现
ArchitectureDto architectureDto = DocDemo.CreateDoc5();
// 创建好index请求
IndexRequest indexRequest = new IndexRequest("architecture_index");
// 设置索引
indexRequest.id("5");
// 设置超时时间(默认)
indexRequest.timeout(TimeValue.timeValueSeconds(5));
// 往请求中添加数据
indexRequest.source(JSON.toJSONString(architectureDto), XContentType.JSON);
//执行添加请求
IndexResponse indexResponse = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
System.out.println(indexResponse);
}
@Test
public void getDoc() throws IOException {
//获得查询索引的请求对象
GetRequest gerRequest = new GetRequest("architecture_index").id("2");
//获得文档对象
GetResponse doc = restHighLevelClient.get(gerRequest, RequestOptions.DEFAULT);
//获得文档数据
System.out.println(doc.getSourceAsString());
}
@Test
public void delDoc() throws IOException {
//获得删除的索引请求对象
DeleteRequest delRequest = new DeleteRequest("architecture_index").id("1");
//删除文档
DeleteResponse delete = restHighLevelClient.delete(delRequest, RequestOptions.DEFAULT);
System.out.println(delete.getIndex());
}
@Test
public void delIndex() throws IOException {
IndicesClient indices = restHighLevelClient.indices();
DeleteIndexRequest delReq = new DeleteIndexRequest("architecture_index");
AcknowledgedResponse delete = indices.delete(delReq, RequestOptions.DEFAULT);
System.out.println(delete.isAcknowledged());
}
@Test
public void contextLoads() throws IOException {
//查询mysql中所有数据
List<ArchitectureDto> architectures = new ArrayList<>();
//创建批量处理对象
BulkRequest bulkRequest = new BulkRequest();
//循环添加新增处理请求
for (ArchitectureDto architecture : architectures) {
String architecturJson = JSON.toJSONString(architecture);
IndexRequest indexRequest = new IndexRequest("architecture_index").id(architecture.getId() + "").source(architecturJson, XContentType.JSON);
bulkRequest.add(indexRequest);
}
//提交批量处理对象
BulkResponse bulk = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
//查看添加状态
System.out.println(bulk.status());
}
通过restHighLevelClient对象对ElasticSearch数据库进行高级查询操作
@RunWith(SpringRunner.class)
@SpringBootTest(classes = EsApplication.class)
public class EsSearchTest {
@Autowired
private RestHighLevelClient restHighLevelClient;
/**
* 查询条件数据 匹配查询不到将字段类似设置为.keyword
* @throws IOException
*/
@Test
public void searchAll() throws IOException {
//定义请求对象
SearchRequest request = new SearchRequest("architecture_index");
//制定检索条件
SearchSourceBuilder builder = new SearchSourceBuilder();
builder.query(QueryBuilders.matchAllQuery()); //查询所有
// builder.query(QueryBuilders.termQuery("address","huahexi777")); //非String 类型查询
// builder.query(QueryBuilders.termQuery("location.lat",33.2)); //非String 类型查询
// builder.query(QueryBuilders.matchPhraseQuery("area","高新区")); //精准查询String
// builder.query(QueryBuilders.matchQuery("area.keyword","高新区")); // 不能匹配到
// builder.query(QueryBuilders.termQuery("area.keyword","高新区"));
// builder.sort("price", SortOrder.DESC);
request.source(builder);
//获得文档对象
SearchResponse search = restHighLevelClient.search(request, RequestOptions.DEFAULT);
//获得文档数据
for (SearchHit hit : search.getHits().getHits()) {
ArchitectureDto art = JSONObject.parseObject(hit.getSourceAsString(), ArchitectureDto.class);
System.out.println(JSON.toJSONString(art));
}
}
/**
* 类似于数据库的 or 查询
* @throws IOException
*/
@Test
public void searchByBolt() throws IOException {
//定义请求对象
SearchRequest request = new SearchRequest("architecture_index");
//制定检索条件
SearchSourceBuilder builder = new SearchSourceBuilder();
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.should(QueryBuilders.matchQuery("price",10));
boolQueryBuilder.should(QueryBuilders.matchQuery("score",4.6).boost(10));
builder.query(boolQueryBuilder); //非String 类型查询
request.source(builder);
//获得文档对象
SearchResponse search = restHighLevelClient.search(request, RequestOptions.DEFAULT);
//获得文档数据
for (SearchHit hit : search.getHits().getHits()) {
ArchitectureDto art = JSONObject.parseObject(hit.getSourceAsString(), ArchitectureDto.class);
System.out.println(JSON.toJSONString(art));
}
}
/**
* 查询部分字段
* @throws IOException
*/
@Test
public void searchByParam() throws IOException {
//定义请求对象
SearchRequest request = new SearchRequest("architecture_index");
//制定检索条件
SearchSourceBuilder builder = new SearchSourceBuilder();
builder.query(QueryBuilders.matchAllQuery()); //查询所有
String[] includes = {"name","address","price"};
String[] excludes = {};
/** 会多出一个score字段 默认值都为0 具体原因不详 */
builder.fetchSource(includes,excludes);
request.source(builder);
//获得文档对象
SearchResponse search = restHighLevelClient.search(request, RequestOptions.DEFAULT);
//获得文档数据
for (SearchHit hit : search.getHits().getHits()) {
ArchitectureDto art = JSONObject.parseObject(hit.getSourceAsString(), ArchitectureDto.class);
System.out.println(JSON.toJSONString(art));
}
}
/**
* 范围查询 大于小于
* @throws IOException
*/
@Test
public void searchByFilter() throws IOException {
//定义请求对象
SearchRequest request = new SearchRequest("architecture_index");
//制定检索条件
SearchSourceBuilder builder = new SearchSourceBuilder();
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
//定制查询条件
boolQueryBuilder.filter (QueryBuilders.rangeQuery("price").gte(10).lte(30));
builder.query(boolQueryBuilder); //非String 类型查询
request.source(builder);
SearchResponse search = restHighLevelClient.search(request, RequestOptions.DEFAULT);
for (SearchHit hit : search.getHits().getHits()) {
ArchitectureDto art = JSONObject.parseObject(hit.getSourceAsString(), ArchitectureDto.class);
System.out.println(JSON.toJSONString(art));
}
}
/**
* 迷糊查询
* @throws IOException
*/
@Test
public void searchByLike() throws IOException {
//定义请求对象
SearchRequest request = new SearchRequest("architecture_index");
//制定检索条件
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//定制查询条件
TermQueryBuilder builder = QueryBuilders.termQuery("name.keyword","北京大").fuzziness(Fuzziness.ONE));
searchSourceBuilder.query(builder);
request.source(searchSourceBuilder);
SearchResponse search = restHighLevelClient.search(request, RequestOptions.DEFAULT);
for (SearchHit hit : search.getHits().getHits()) {
ArchitectureDto art = JSONObject.parseObject(hit.getSourceAsString(), ArchitectureDto.class);
System.out.println(JSON.toJSONString(art));
}
}
}
以上就是SpringBoot集成Elasticsearch数据库内容,在验证过程中遇到很多问题,如果大家在使用过程中遇到问题欢迎留言。