附:Elasticsearch 环境搭建,可参考:Linux Centos7.5 安装elasticsearch(单机/集群)
1.demo结构:
2.pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
.....
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
<scope>provided</scope>
</dependency>
3.实体类:
package com.lucifer.esdemo.pojo;
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
/**
* @author: Lucifer
* @date: 2020/3/9
* @description: 实体类
*/
@Data
@Document(indexName = "stu")
public class Stu {
@Id
private Long stuId;
@Field(store = true)
private String name;
@Field(store = true)
private Integer age;
@Field(store = true)
private Float money;
@Field(store = true,type = FieldType.Keyword)
private String sign;
@Field(store = true)
private String description;
}
4.application.yml:
spring:
data:
elasticsearch:
cluster-name: lucifer-es-cluster
cluster-nodes: 192.168.160.130:9300,192.168.160.133:9300,192.168.160.134:9300
ps:cluster-name;cluster-nodes 两个属性废弃了
5.测试类:
package com.lucifer.esdemo;
import com.lucifer.esdemo.pojo.Stu;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortOrder;
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.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.SearchResultMapper;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl;
import org.springframework.data.elasticsearch.core.query.*;
import java.util.*;
@SpringBootTest
public class EsDemoApplicationTests {
@Autowired
private ElasticsearchTemplate elasticsearchTemplate;
/**
* 生成测试数据
*/
@Test
public void createStu() {
List<IndexQuery> indexQueryList = new ArrayList<>();
for (int i = 0; i < 10; i++) {
Stu stu = new Stu();
stu.setStuId((long) new Random().nextInt(1500));
stu.setName("王五" + i);
stu.setAge(new Random().nextInt(100));
stu.setMoney(new Random().nextFloat() + 10);
stu.setSign("隔壁老王" + i);
stu.setDescription("不可描述" + i);
indexQueryList.add(new IndexQueryBuilder().withObject(stu).build());
}
elasticsearchTemplate.bulkIndex(indexQueryList);
}
//==========================================【索引】====================================================
/**
* 创建索引,不过不建议使用ElasticsearchTemplate 代码的方式 创建
*/
@Test
public void createIndexStu() {
Stu stu = new Stu();
stu.setStuId(1002L);
stu.setName("张三");
stu.setAge(25);
stu.setMoney(20.5F);
stu.setSign("lucifer");
stu.setDescription("hello world");
IndexQuery indexQuery = new IndexQueryBuilder().withObject(stu).build();
String index = elasticsearchTemplate.index(indexQuery);
System.out.println("index:" + index);
}
/**
* 删除索引
*/
@Test
public void deleteIndexStu() {
boolean b = elasticsearchTemplate.deleteIndex(Stu.class);
System.out.println("result:" + b);
}
//==========================================【修改文档】====================================================
/**
* 修改文档
*/
@Test
public void updateStuDoc() {
Map<String, Object> sourceMap = new HashMap<>();
sourceMap.put("money", 33.04f);
sourceMap.put("age", 18);
IndexRequest indexRequest = new IndexRequest();
indexRequest.source(sourceMap);
// 类似sql语法: update stu set sign='abc',age=33,money=88.6 where docId='1002'
UpdateQuery updateQuery = new UpdateQueryBuilder().withClass(Stu.class).withId("1002").withIndexRequest(indexRequest).build();
UpdateResponse update = elasticsearchTemplate.update(updateQuery);
System.out.println("result:" + update);
}
//=============================================【查询文档】=================================================
/**
* 查询文档
*/
@Test
public void getStuDoc() {
GetQuery query = new GetQuery();
query.setId("1002");
Stu stu = elasticsearchTemplate.queryForObject(query, Stu.class);
System.out.println("result:" + stu);
}
//==========================================【删除文档】======================================================
/**
* 删除文档
*/
@Test
public void deleteStuDoc() {
elasticsearchTemplate.delete(Stu.class, "1002");
}
//==========================================【分页查询文档】======================================================
@Test
public void searchStuDoc() {
PageRequest pageRequest = PageRequest.of(0, 10);
SearchQuery searchQuery = new NativeSearchQueryBuilder().
withQuery(QueryBuilders.matchQuery("description", "hello 不可")).
withPageable(pageRequest).build();
AggregatedPage<Stu> stus = elasticsearchTemplate.queryForPage(searchQuery, Stu.class);
System.out.println("检索后总分页数目为:" + stus.getTotalPages());
for (Stu stu : stus) {
System.out.println(stu);
}
}
//==========================================【高亮】======================================================
@Test
public void highlightStuDoc() {
String preTag = "<font color='red'>";
String postTags = "</font>";
//按年龄排序(倒序)
SortBuilder sortBuilder = new FieldSortBuilder("age");
sortBuilder.order(SortOrder.DESC);
PageRequest pageRequest = PageRequest.of(0, 5);
SearchQuery searchQuery = new NativeSearchQueryBuilder().
withQuery(QueryBuilders.matchQuery("description", "hello 不可")).
withHighlightFields(new HighlightBuilder.Field("description").
preTags(preTag).
postTags(postTags)).
withSort(sortBuilder).
withPageable(pageRequest).build();
AggregatedPage<Stu> stus = elasticsearchTemplate.queryForPage(searchQuery, Stu.class, new SearchResultMapper() {
@Override
public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> clazz, Pageable pageable) {
List<Stu> hitsHighlight = new ArrayList<>();
SearchHits hits = response.getHits();
for (SearchHit hit : hits) {
Map<String, HighlightField> highlightFields = hit.getHighlightFields();
HighlightField highlightField = highlightFields.get("description");
String description = highlightField.getFragments()[0].toString();
Object stuId = hit.getSourceAsMap().get("stuId");
String name = (String) hit.getSourceAsMap().get("name");
Integer age = (Integer) hit.getSourceAsMap().get("age");
String sign = (String) hit.getSourceAsMap().get("sign");
Object money = hit.getSourceAsMap().get("money");
Stu stu = new Stu();
stu.setStuId(Long.valueOf(stuId.toString()));
stu.setName(name);
stu.setAge(age);
stu.setSign(sign);
stu.setMoney(Float.valueOf(money.toString()));
stu.setDescription(description);
hitsHighlight.add(stu);
}
if (hitsHighlight.size() > 0) {
return new AggregatedPageImpl<>((List<T>) hitsHighlight);
}
return null;
}
@Override
public <T> T mapSearchHit(SearchHit searchHit, Class<T> type) {
return null;
}
});
System.out.println("检索后总分页数目为:" + stus.getTotalPages());
for (Stu stu : stus) {
System.out.println(stu);
}
}
}