前言
你可以通过官网文档看到ElasticSearch7和6的变化,本文的重点在于在SpringBoot环境中使用ElasticSearch7。
软件安装
从官网下载ElasticSearch ,我这里使用的是7.9.3版本 , 下载Kibana也是7.9.3,以及IK分词器,下载好之后把ElasticSearch进行解压:
把IK分词器解压到plugins/ik目录中,如下:
解压Kibana,目录结构如下
启动ElasticSearch : elasticsearch-7.9.3\bin\elasticsearch.bat
, 然后启动Kibana :\kibana-7.9.3-windows-x86_64\bin\kibana.bat
,访问kibana: http://localhost:5601
Spring整合ES7
第一步:导入依赖,SpringBoot使用的是2.4;需要注意版本兼容7.9.3
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.0</version>
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.71</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
第二步:启动类常规写法,yaml配置es地址
server:
port: 1000
spring:
elasticsearch:
rest:
uris:
- http://localhost:9200
第三步:编写ES的Doc对象
@Data
//定义索引,7以上的版本去掉了type属性
@Document(indexName = "goodsorder", shards = 1, replicas = 1)
@AllArgsConstructor
@NoArgsConstructor
public class OrderDoc implements Serializable {
@Id
@Field(type = FieldType.Keyword)
private String id;
@Field(type = FieldType.Long)
private Long orderNo;
@Field(type = FieldType.Text, analyzer = "ik_smart", searchAnalyzer = "ik_max_word")
private String title;
//用来封装高亮的结果
private Map<String, List<String>> highlights;
public OrderDoc(String id, Long orderNo ,String title){
this.id = id;
this.orderNo = orderNo;
this.title =title;
}
}
第四步:编写Repository接口
@Repository
//泛型是Doc对象和ID的类型
public interface OrderRepository extends ElasticsearchRepository<OrderDoc, String> {
}
第五步:编写Service接口,定义基本的CRUD方法
public interface OrderDocService {
void saveAll(List<OrderDoc> orderDocs);
OrderDoc findById(String id);
void deleteById(String id);
void updateById(OrderDoc orderDoc);
PageResponse<OrderDoc> findList(OrderDoc orderDoc, Integer pageIndex, Integer pageSize);
PageResponse<OrderDoc> findAll(Integer pageIndex, Integer pageSize);
PageResponse<OrderDoc> findHighlight(OrderDoc orderDoc, Integer pageIndex, Integer pageSize);
}
下面是实现类,注入OrderRepository和ElasticsearchRestTemplate实现CRUD工作
@Service
public class OrderDocServiceImpl implements OrderDocService {
@Autowired
private OrderRepository orderRepository;
@Autowired
private ElasticsearchRestTemplate template;
@Override
public void saveAll(List<OrderDoc> orderDocs) {
orderRepository.saveAll(orderDocs);
}
@Override
public OrderDoc findById(String id) {
return orderRepository.findById(id).orElse(null);
}
@Override
public void deleteById(String id) {
orderRepository.deleteById(id);
}
@Override
public void updateById(OrderDoc orderDoc) {
orderRepository.save(orderDoc);
}
@Override
public PageResponse<OrderDoc> findList(OrderDoc orderDoc, Integer pageIndex, Integer pageSize) {
CriteriaQuery criteriaQuery = new CriteriaQuery(
new Criteria().and("title").contains(orderDoc.getTitle()),PageRequest.of(pageIndex,pageSize));
SearchHits<OrderDoc> searchHits = template.search(criteriaQuery, OrderDoc.class);
List<OrderDoc> orderDocList = searchHits.getSearchHits().stream()
.map(orderDocSearchHit -> orderDocSearchHit.getContent()).collect(Collectors.toList());
return new PageResponse<OrderDoc>(searchHits.getTotalHits() ,orderDocList);
}
@Override
public PageResponse<OrderDoc> findAll(Integer pageIndex, Integer pageSize) {
Page<OrderDoc> page = orderRepository.findAll(PageRequest.of(pageIndex, pageSize));
return new PageResponse<OrderDoc>(page.getTotalElements(),page.getContent());
}
@Override
public PageResponse<OrderDoc> findHighlight(OrderDoc orderDoc, Integer pageIndex, Integer pageSize) {
//查询条件
CriteriaQuery criteriaQuery = new CriteriaQuery(
new Criteria().and("title").contains(orderDoc.getTitle()),
PageRequest.of(pageIndex,pageSize));
//高亮字段
HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.field("title").preTags("<font style='color:red'>").postTags("</font>");
criteriaQuery.setHighlightQuery(new HighlightQuery(highlightBuilder));
//搜索结果
SearchHits<OrderDoc> searchHits = template.search(criteriaQuery, OrderDoc.class);
List<OrderDoc> orderDocList = searchHits.get().map(searchHit -> {
//把高亮结果添加到doc中中
OrderDoc doc = searchHit.getContent();
//获取高亮
doc.setHighlights(searchHit.getHighlightFields());
return doc;
}).collect(Collectors.toList());
//处理结果
return new PageResponse<>(searchHits.getTotalHits() , orderDocList);
}
}
下面是需要的结果对象
@Data
@AllArgsConstructor
@NoArgsConstructor
public class PageResponse<T> {
private Long total;
private List<T> list;
}
第六步:编写单元测试
@RunWith(SpringRunner.class)
@SpringBootTest(classes = ApplicationStarter.class)
public class OrderDocServiceTest {
@Autowired
private OrderDocService orderDocService;
@Test
public void saveAll() {
orderDocService.saveAll(Arrays.asList(
new OrderDoc("1",100000l,"苹果电脑"),
new OrderDoc("2",100000l,"苹果电脑"),
new OrderDoc("3",100000l,"苹果电脑"),
new OrderDoc("4",100000l,"苹果电脑"),
new OrderDoc("5",100000l,"苹果电脑"),
new OrderDoc("6",100000l,"苹果电脑"),
new OrderDoc("7",100000l,"苹果电脑")
));
}
@Test
public void findById() {
System.out.println(orderDocService.findById("1"));
}
@Test
public void deleteById() {
orderDocService.deleteById("1");
}
@Test
public void updateById() {
OrderDoc orderDoc = orderDocService.findById("1");
orderDoc.setTitle("华为电脑");
orderDocService.updateById(orderDoc);
}
@Test
public void findList() {
OrderDoc orderDoc = new OrderDoc(null, 100l, "电脑");
PageResponse<OrderDoc> response = orderDocService.findList(orderDoc, 0, 10);
System.out.println(response.getTotal());
response.getList().forEach(System.out::println);
}
@Test
public void findAll() {
PageResponse<OrderDoc> response = orderDocService.findAll( 0, 10);
System.out.println(response.getTotal());
response.getList().forEach(System.out::println);
}
@Test
public void findHighlight() {
OrderDoc orderDoc = new OrderDoc(null, 100l, "电脑",null);
PageResponse<OrderDoc> response = orderDocService.findHighlight( orderDoc,0, 10);
System.out.println(response.getTotal());
response.getList().forEach(System.out::println);
}
}