1.针对 spring-boot-starter-elasticsearch的一些新特性进行了一个demo开发
1.2 主要包括路由@Routing和生命周期的回调,以及审计的用法,以及Elasticseach本身的乐观锁的实验,废话不多说,直接上代码
1.3 钩子方法
package com.example.demo.callback;
import com.example.demo.entity.TestESEntity;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.annotation.Order;
import org.springframework.data.elasticsearch.core.document.Document;
import org.springframework.data.elasticsearch.core.event.AfterConvertCallback;
import org.springframework.data.elasticsearch.core.event.AfterSaveCallback;
import org.springframework.data.elasticsearch.core.event.BeforeConvertCallback;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.stereotype.Component;
@Order(1)
@Component
@Slf4j
public class TestCallBack implements
BeforeConvertCallback<TestESEntity>,
AfterConvertCallback<TestESEntity>,
AfterSaveCallback<TestESEntity> {
@Override
public TestESEntity onBeforeConvert(TestESEntity entity, IndexCoordinates index) {
log.info("onBeforeConvert:{}", entity);
return entity;
}
@Override
public TestESEntity onAfterConvert(TestESEntity entity, Document document, IndexCoordinates indexCoordinates) {
log.info("onAfterConvert:entity{},document{}", entity, document);
return entity;
}
@Override
public TestESEntity onAfterSave(TestESEntity entity, IndexCoordinates index) {
log.info("onAfterSave:entity{}", entity);
return entity;
}
}
1.4 审计获取用户信息
package com.example.demo.config;
import org.springframework.data.domain.AuditorAware;
import org.springframework.stereotype.Component;
import java.util.Optional;
@Component
public class TestESAuditorAware implements AuditorAware<String> {
@Override
public Optional<String> getCurrentAuditor() {
return Optional.of("zhang-san");
}
}
1.5DAO层方法
package com.example.demo.dao;
import com.example.demo.entity.TestESEntity;
import com.example.demo.mapper.TestMapper;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.script.Script;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.RefreshPolicy;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.document.Document;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.elasticsearch.core.query.ByQueryResponse;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.UpdateQuery;
import org.springframework.stereotype.Repository;
import javax.annotation.Resource;
import java.util.*;
@Repository
public class TestESDAO {
@Resource
private ElasticsearchOperations elasticsearchOperations;
@Resource
private TestMapper testMapper;
public void save() {
String[] name = {"xinLang", "tengXun", "aLiBaBa", "meiTuan", "gaoDe", "diDi", "pingGuo"};
String[] nameChina = {"新浪公司", "腾讯集团", "阿里巴巴集团", "美团公司", "高德公司", "滴滴公司", "苹果集团"};
List<TestESEntity> testESEntityArrayList = new ArrayList<>();
for (int i = 1; i < 15; i++) {
TestESEntity testEsEntity = new TestESEntity();
testEsEntity.setId((long) i);
int index = i % 7;
testEsEntity.setName(name[index]);
testEsEntity.setNameChina(nameChina[index]);
testEsEntity.setUpdateField(7777777);
testEsEntity.setFirst(true);
testESEntityArrayList.add(testEsEntity);
}
elasticsearchOperations.save(testESEntityArrayList);
}
public void updateSave() {
TestESEntity testESEntity = testMapper.queryTestESEntityById(1L);
testESEntity.setUpdateField(9999);
elasticsearchOperations.save(testESEntity);
}
public void search() {
NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder().withRoute("tengXun");
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(QueryBuilders.multiMatchQuery("腾讯", "nameChina"));
HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.field("nameChina");
highlightBuilder.highlightQuery(boolQueryBuilder);
nativeSearchQueryBuilder.withQuery(boolQueryBuilder);
nativeSearchQueryBuilder.withHighlightBuilder(highlightBuilder);
nativeSearchQueryBuilder.withPageable(PageRequest.of(0, 5));
NativeSearchQuery build = nativeSearchQueryBuilder.build();
SearchHits<TestESEntity> searchHits = elasticsearchOperations.search(build, TestESEntity.class);
long totalHits = searchHits.getTotalHits();
float maxScore = searchHits.getMaxScore();
System.out.println("totalHits:" + totalHits + ";maxScore:" + maxScore);
for (SearchHit<TestESEntity> searchHit : searchHits) {
TestESEntity testESEntity = searchHit.getContent();
System.out.println(testESEntity);
Map<String, List<String>> highlightFields = searchHit.getHighlightFields();
System.out.println(highlightFields);
float score = searchHit.getScore();
System.out.println(score);
}
}
public void deleteByQuery() {
NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
nativeSearchQueryBuilder.withQuery(QueryBuilders.boolQuery().must(QueryBuilders.multiMatchQuery("公司", "nameChina")));
SearchHits<TestESEntity> search = elasticsearchOperations.search(nativeSearchQueryBuilder.build(), TestESEntity.class);
for (SearchHit<TestESEntity> sevenVersionTestESSearchHit : search) {
System.out.println(sevenVersionTestESSearchHit.getContent());
}
ByQueryResponse delete = elasticsearchOperations.delete(nativeSearchQueryBuilder.build(), TestESEntity.class);
System.out.println(delete.getTotal());
search = elasticsearchOperations.search(nativeSearchQueryBuilder.build(), TestESEntity.class);
for (SearchHit<TestESEntity> sevenVersionTestESSearchHit : search) {
System.out.println(sevenVersionTestESSearchHit.getContent());
}
}
public void updateByQuery() {
NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder().withRoute("tengXun");
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(QueryBuilders.multiMatchQuery("腾讯", "nameChina"));
nativeSearchQueryBuilder.withQuery(boolQueryBuilder);
UpdateQuery.Builder builder = UpdateQuery.builder(nativeSearchQueryBuilder.build());
HashMap<String, Object> paramsMap = new HashMap<>();
paramsMap.put("up", "up");
builder.withScriptType(org.springframework.data.elasticsearch.core.ScriptType.INLINE);
builder.withLang(Script.DEFAULT_SCRIPT_LANG);
builder.withParams(paramsMap);
builder.withScript("ctx._source.up = params.up");
builder.withRetryOnConflict(5);
builder.withRouting("tengXun");
ByQueryResponse byQueryResponse = elasticsearchOperations.updateByQuery(builder.build(), elasticsearchOperations.getIndexCoordinatesFor(TestESEntity.class));
long total = byQueryResponse.getTotal();
System.out.println(total);
}
public void updateById() {
List<UpdateQuery> testClasses = new ArrayList<>();
IndexCoordinates indexCoordinates = elasticsearchOperations.getIndexCoordinatesFor(TestESEntity.class);
for (int i = 0; i < 75; i++) {
UpdateQuery.Builder builder = UpdateQuery.builder("1");
builder.withRouting("tengXun");
LinkedHashMap<String, Integer> linkedHashMap = new LinkedHashMap<>();
linkedHashMap.put("updateField", i);
Document document = Document.from(linkedHashMap);
builder.withDocument(document);
builder.withRetryOnConflict(100);
builder.withRefreshPolicy(RefreshPolicy.IMMEDIATE);
testClasses.add(builder.build());
}
testClasses.stream().parallel().forEach(x -> {
elasticsearchOperations.update(x, indexCoordinates);
});
}
public void count() {
System.out.println(testMapper.count());
}
}
1.6 实体定义
package com.example.demo.entity;
import org.springframework.data.annotation.*;
import org.springframework.data.domain.Persistable;
import org.springframework.data.elasticsearch.annotations.*;
@Document(indexName = "test_es")
@Routing(value = "@GenerateRouting.getRouting(#entity)")
@Setting(shards = 5)
public class TestESEntity implements Persistable<Long> {
@Id
@Field(name = "id", type = FieldType.Keyword)
private Long id;
@Field(type = FieldType.Keyword)
private String name;
@Field(type = FieldType.Text)
private String nameChina;
@Field(type = FieldType.Integer)
private Integer updateField;
@CreatedDate
@Field(type = FieldType.Long)
private Long createTime;
@CreatedBy
@Field(type = FieldType.Keyword)
private String createBy;
@LastModifiedDate
@Field(type = FieldType.Long)
private Long updateTime;
@LastModifiedBy
@Field(type = FieldType.Keyword)
private String updateBy;
@Transient
private boolean first;
@Override
public Long getId() {
return id;
}
@Override
public boolean isNew() {
return first;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getNameChina() {
return nameChina;
}
public void setNameChina(String nameChina) {
this.nameChina = nameChina;
}
public Integer getUpdateField() {
return updateField;
}
public void setUpdateField(Integer updateField) {
this.updateField = updateField;
}
public Long getCreateTime() {
return createTime;
}
public void setCreateTime(Long createTime) {
this.createTime = createTime;
}
public String getCreateBy() {
return createBy;
}
public void setCreateBy(String createBy) {
this.createBy = createBy;
}
public Long getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Long updateTime) {
this.updateTime = updateTime;
}
public String getUpdateBy() {
return updateBy;
}
public void setUpdateBy(String updateBy) {
this.updateBy = updateBy;
}
public boolean isFirst() {
return first;
}
public void setFirst(boolean first) {
this.first = first;
}
@Override
public String toString() {
return "TestESEntity{" +
"id=" + id +
", name='" + name + '\'' +
", nameChina='" + nameChina + '\'' +
", updateField=" + updateField +
", createTime=" + createTime +
", createBy='" + createBy + '\'' +
", updateTime=" + updateTime +
", updateBy='" + updateBy + '\'' +
", first=" + first +
'}';
}
}
1.7Mapper定义
package com.example.demo.mapper;
import com.example.demo.entity.TestESEntity;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
public interface TestMapper extends ElasticsearchRepository<TestESEntity, Long> {
long count();
TestESEntity queryTestESEntityById(Long id);
}
1.8 Routing自定义
package com.example.demo.routing;
import com.example.demo.entity.TestESEntity;
import org.springframework.stereotype.Service;
@Service(value = "GenerateRouting")
public class TestESGenerateRouting {
public String getRouting(TestESEntity testEsEntity) {
System.out.println("get into getRouting");
return testEsEntity.getName();
}
}
1.9启动类配置
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.elasticsearch.config.EnableElasticsearchAuditing;
import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;
@SpringBootApplication
@EnableElasticsearchRepositories
@EnableElasticsearchAuditing
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
2.0测试类
package com.example.demo;
import com.example.demo.dao.TestESDAO;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
class DemoApplicationTests {
@Autowired
private TestESDAO testESDAO;
@Test
public void save() {
testESDAO.save();
}
@Test
public void updateSave() {
testESDAO.updateSave();
}
@Test
public void search() {
testESDAO.search();
}
@Test
public void deleteByQuery() {
testESDAO.deleteByQuery();
}
@Test
public void updateByQuery() {
testESDAO.updateByQuery();
}
@Test
public void updateById() {
testESDAO.updateById();
}
@Test
public void count() {
testESDAO.count();
}
}
2.1 POM文件
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.5.7
com.example
demo
0.0.1-SNAPSHOT
demo
Demo project for Spring Boot
1.8
7.12.1
org.springframework.boot
spring-boot-starter-data-elasticsearch
2.5.7
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
test
org.projectlombok
lombok
RELEASE
compile
org.springframework.boot
spring-boot-maven-plugin
2.2.5.RELEASE
完整代码路径
https://download.csdn.net/download/xuexi_deng/53381462