ElasticSearch ElasticSearchRestTemplate使用
环境准备 SpringBoot 2.4.3 es版本 7.11.1 jdk 1.8
application.yml
#因为本机9200是默认链接地址,未设置用户名密码,唯一未配,如需配置,以下地址配置
pom.xml
<properties>
<java.version>1.8</java.version>
<!-- es版本与依赖对应 -->
<elasticsearch.version>7.11.1</elasticsearch.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
创建索引
这里主要是以注解的方式创建索引,建立实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Document(indexName = "jd") // 所属索引名称
public class Content implements Serializable {
@Id // 文档中的ID主键 必需
private Integer id;
@Field(value = "img") // 文档中img字段
private String img;
@Field(value = "price")
private String price;
@Field(value = "title")
private String title;
}
增删改操作
增删改操作使用,这里不使用ElasticSearchRestTemplate,使用继承ElasticsearchRepository<T, ID>的接口进行操作。
package com.huyonghao.esapi.service;
import com.huyonghao.esapi.model.Content;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Service;
// 建立继承接口注入SpringBoot中,此处不用实现接口,代理对象动态代理生成
@Service
public interface ContentService extends ElasticsearchRepository<Content, Integer> {
}
ElasticsearchRepository<Content, Integer>中的两个泛型,前者是索引中文档对应的对象即Content,后者是主键的类型,因为Content中id定义为Integer 故为Integer。
该接口有很多方法直接调用,方法可见名知意,不详细赘述。
使用ElasticSearchRestTemplate进行查询
查询之前首先根据增删改API创建索引并存入相应数据。
查看分析调用接口,因为此处实体类中已有索引名称,所以使用第二个有参方法。传入一个Query类型对象与接收的实体类,即Content。
查看源码定位到Query接口的实现类NativeSearchQuery类,该类中含有许多属性。
public class NativeSearchQuery extends AbstractQuery {
// 查询条件 比如match term 等QueryBuilder都是其子类
@Nullable private final QueryBuilder query;
// filter查询条件
@Nullable private QueryBuilder filter;
// 排序条件
@Nullable private List<SortBuilder<?>> sorts;
private final List<ScriptField> scriptFields = new ArrayList<>();
// 去重
@Nullable private CollapseBuilder collapseBuilder;
// 聚合函数
@Nullable private List<AbstractAggregationBuilder<?>> aggregations;
// 高亮
@Nullable private HighlightBuilder highlightBuilder;
@Nullable private HighlightBuilder.Field[] highlightFields;
@Nullable private List<IndexBoost> indicesBoost;
}
多查询条件不详细说明,下图API:
package com.huyonghao.esapi;
import com.huyonghao.esapi.model.Content;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import java.util.List;
@SpringBootTest
class EsApiApplicationTests {
@Autowired
private ElasticsearchRestTemplate restTemplate;
@Test
void jdHighLight() {
// 高亮
HighlightBuilder highlightBuilder = new HighlightBuilder().preTags("<span style='color:red'>").postTags("</span>").field("title");
// 分页功能实现 5页
Pageable pageable = PageRequest.of(0, 5);
// 排序功能实现
FieldSortBuilder fieldSortBuilder = new FieldSortBuilder("_score");
// 条件查询 Match条件
MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("title", "Lebron");
// Query对象 建造者模式 其中的分页和排序同样看代码可知。
NativeSearchQuery query = new NativeSearchQueryBuilder().withQuery(matchQueryBuilder).withFields("title", "id", "img", "price")
.withHighlightBuilder(highlightBuilder).withPageable(pageable).withSort(fieldSortBuilder).build();
// 查询
SearchHits<Content> hits = restTemplate.search(query, Content.class);
List<SearchHit<Content>> searchHits = hits.getSearchHits();
System.out.println("一共" + searchHits.size() + "个");
for (SearchHit<Content> searchHit : searchHits) {
// 遍历返回命中结果
Content content = searchHit.getContent();
// 获取高亮字段
List<String> titleHighLightList = searchHit.getHighlightField("title");
// 将高亮字段替换查询出的对象中的title
if (titleHighLightList != null) {
content.setTitle(titleHighLightList.get(0));
}
System.out.println(content);
}
}
}
输出结果:
一共3个
Content(id=23, img=//img11.360buyimg.com/n7/jfs/t1/164431/15/12012/241074/604b878bEa3eab8ec/8718d814ece40789.jpg, price=¥358.00, title=詹姆斯篮球鞋18代男新款<span style='color:red'>Lebron</span>詹皇秋冬紫金重器黑白粉鸳鸯中国限定高帮战靴运动鞋 反转鸳鸯 39 本店产品均有运费险,支持七天无理由退换,售后无忧!)
Content(id=74, img=//img10.360buyimg.com/n7/jfs/t1/168878/38/7340/162925/60327ec5E81fe0acf/ca6b688e719cc17f.jpg, price=¥328.00, title=詹姆斯18代篮球鞋男詹16king雄狮球鞋詹皇15鸳鸯联名彩虹17战靴运动鞋 <span style='color:red'>Lebron</span> 16 灰彩虹 40 本店产品均有运费险,支持七天无理由退换,售后无忧!)
Content(id=0, img=//img13.360buyimg.com/n7/jfs/t1/170095/21/12112/218881/604b878bE33736b23/ef53a6182897c50b.jpg, price=¥358.00, title=詹姆斯篮球鞋18代男新款<span style='color:red'>Lebron</span>詹皇秋冬紫金重器黑白粉鸳鸯中国限定高帮战靴运动鞋 紫金重器 43)