ElasticSearch与SpringBoot集成-ElasticsearchRestTemplate
本文内容纲要:
1.简介
SpringBoot提供了与ElasticSearch的集成的starter包,并封装了ElasticsearchRestTemplate类,还实现了与Java对象与ElasticSearch索引的映射关系,可以采用与JPA相似的Repository接口,来操作ES数据。
需要使用maven引用以下依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
<exclusions>
<exclusion>
<groupId>org.elasticsearch.client</groupId>
<artifactId>transport</artifactId>
</exclusion>
<exclusion>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>transport</artifactId>
<version>6.5.0</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>6.5.0</version>
</dependency>
注意:以上的依赖版本可以根据你使用的ES的版本来定。比如我当前的ElasticSearch的版本是6.5.0,就需要手动替换成6.5.0版本的jar包。
2.配置文件
2.1application.yml
在SpringBoot项目中application.yml文件中增加以下配置:
spring:
elasticsearch:
rest:
uris:http://192.168.220.11:9200---ES的连接地址,多个地址用逗号分隔
username:---用户名
password:---密码
connection-timeout:1000---连接超时时间
read-timeout:1000---读取超时时间
2.2创建映射对象
我这里定义了一个员工类,并使用@Document定义员工类关联的index索引、typeso因类型,shards主分区,replicas副分区。
在@Document中有个属性是createIndex,表示当索引不存在时,操作这个对象会默认创建索引,默认为true。如果你的索引设置比较多,就把createIndex设置为false,再通过其他接口手动触发创建索引操作。
@Id表示索引的主键
@Field用来描述字段的ES数据类型,是否分词等配置,等于Mapping描述
/**
*员工对象
*<p>
*注解:@Document用来声明Java对象与ElasticSearch索引的关系
*indexName索引名称
*type索引类型
*shards主分区数量,默认5
*replicas副本分区数量,默认1
*createIndex索引不存在时,是否自动创建索引,默认true*/
@Getter
@Setter
@NoArgsConstructor
@Accessors(chain=true)
@Document(indexName="employee_index",type="employee_type",shards=1,replicas=0,createIndex=true)
publicclassEmployeeBean{
@Id
privateStringid;
/**
*员工编码
*/
@Field(type=FieldType.Keyword)
privateStringstudentCode;
/**
*员工姓名
*/
@Field(type=FieldType.Keyword)
privateStringname;
/**
*员工简历
*/
@Field(type=FieldType.Text,analyzer="ik_max_word")
privateStringdesc;
/**
*员工住址
*/
@Field(type=FieldType.Text,analyzer="ik_max_word")
privateIntegertype;
/**
*手机号码
*/
@Field(type=FieldType.Keyword)
privateStringmobile;
}
2.3创建Repository接口
Repository需要继承ElasticsearchRepository接口,参数<映射对象,主键ID的数据类型>。之后Repository类就可以使用类似JPA的方法操作ElasticSearch数据。
@Component
publicinterfaceEmployeeRepositoryextendsElasticsearchRepository<EmployeeBean,String>{
}
我们在操作索引和数据时,需要引用这2个类
@Autowired
privateElasticsearchRestTemplaterestTemplate;
@Autowired
privateEmployeeRepositoryrepository;
3.索引操作
3.1判断索引是否存在
/**
*判断索引是否存在
*@returnboolean
*/
publicbooleanindexExists(){
returnrestTemplate.indexExists(EmployeeBean.class);
}
/**
*判断索引是否存在
*@paramindexName索引名称
*@returnboolean
*/
publicbooleanindexExists(StringindexName){
returnrestTemplate.indexExists(indexName);
}
3.2创建索引
/**
*创建索引(推荐使用:因为Java对象已经通过注解描述了Setting和Mapping)
*@returnboolean
*/
publicbooleanindexCreate(){
returnrestTemplate.createIndex(EmployeeBean.class);
}
/**
*创建索引
*@paramindexName索引名称
*@returnboolean
*/
publicbooleanindexCreate(StringindexName){
returnrestTemplate.createIndex(indexName);
}
3.3删除索引
/**
*索引删除
*@paramindexName索引名称
*@returnboolean
*/
publicbooleanindexDelete(StringindexName){
returnrestTemplate.deleteIndex(indexName);
}
4.数据操作
4.1新增数据
/**
*新增数据
*@parambean数据对象
*/
publicvoidsave(EmployeeBeanbean){
repository.save(bean);
}
/**
*批量新增数据
*@paramlist数据集合
*/
publicvoidsaveAll(List<EmployeeBean>list){
repository.saveAll(list);
}
4.2修改数据
/**
*修改数据
*@paramindexName索引名称
*@paramtype索引类型
*@parambean修改数据对象,ID不能为空
*/
publicvoidupdate(StringindexName,Stringtype,EmployeeBeanbean){
UpdateRequestupdateRequest=newUpdateRequest();
updateRequest.retryOnConflict(1);//冲突重试
updateRequest.doc(JSONUtil.toJsonStr(bean),XContentType.JSON);
updateRequest.routing(bean.getId());//默认是_id来路由的,用来路由到不同的shard,会对这个值做hash,然后映射到shard。所以分片
UpdateQueryquery=newUpdateQueryBuilder().withIndexName(indexName).withType(type).withId(bean.getId())
.withDoUpsert(true)//不加默认false。true表示更新时不存在就插入
.withClass(EmployeeBean.class).withUpdateRequest(updateRequest).build();
UpdateResponseupdateResponse=restTemplate.update(query);
}
4.3删除数据
/**
*根据ID,删除数据
*@paramid数据ID
*/publicvoiddeleteById(Stringid){
repository.deleteById(id);
}
/**
*根据对象删除数据,主键ID不能为空
*@parambean对象
*/publicvoiddeleteByBean(EmployeeBeanbean){
repository.delete(bean);
}
/**
*根据对象集合,批量删除
*@parambeanList对象集合
*/publicvoiddeleteAll(List<EmployeeBean>beanList){
repository.deleteAll(beanList);
}
/**
*删除所有
*/publicvoiddeleteAll(){
repository.deleteAll();
}
/**
*根据条件,自定义删除(在setQuery中的条件,可以根据需求自由拼接各种参数,与查询方法一样)
*@paramindexName索引
*@paramtype索引类型
*/publicvoiddelete(StringindexName,Stringtype){
DeleteQuerydeleteQuery=newDeleteQuery();
deleteQuery.setIndex(indexName);
deleteQuery.setType(type);//建index没配置就是类名全小写
deleteQuery.setQuery(newBoolQueryBuilder().must(QueryBuilders.termQuery("mobile","13526568454")));
restTemplate.delete(deleteQuery);
}
4.4批量操作
/**
*批量新增
*@paramindexName索引名称
*@paramtype索引类型
*@parambeanList新增对象集合
*/publicvoidbatchSave(StringindexName,Stringtype,List<EmployeeBean>beanList){
List<IndexQuery>queries=newArrayList<>();
IndexQueryindexQuery;
intcounter=0;
for(EmployeeBeanitem:beanList){
indexQuery=newIndexQuery();
indexQuery.setId(item.getId());
indexQuery.setSource(JSONUtil.toJsonStr(item));
indexQuery.setIndexName(indexName);
indexQuery.setType(type);
queries.add(indexQuery);
//分批提交索引
if(counter!=0&&counter%1000==0){
restTemplate.bulkIndex(queries);
queries.clear();
System.out.println("bulkIndexcounter:"+counter);
}
counter++;
}
//不足批的索引最后不要忘记提交
if(queries.size()>0){
restTemplate.bulkIndex(queries);
}
restTemplate.refresh(indexName);
}
/**
*批量修改
*@paramindexName索引名称
*@paramtype索引类型
*@parambeanList修改对象集合
*/publicvoidbatchUpdate(StringindexName,Stringtype,List<EmployeeBean>beanList){
List<UpdateQuery>queries=newArrayList<>();
UpdateQueryupdateQuery;
UpdateRequestupdateRequest;
intcounter=0;
for(EmployeeBeanitem:beanList){
updateRequest=newUpdateRequest();
updateRequest.retryOnConflict(1);//冲突重试
updateRequest.doc(item);
updateRequest.routing(item.getId());
updateQuery=newUpdateQuery();
updateQuery.setId(item.getId());
updateQuery.setDoUpsert(true);
updateQuery.setUpdateRequest(updateRequest);
updateQuery.setIndexName(indexName);
updateQuery.setType(type);
queries.add(updateQuery);
//分批提交索引
if(counter!=0&&counter%1000==0){
restTemplate.bulkUpdate(queries);
queries.clear();
System.out.println("bulkIndexcounter:"+counter);
}
counter++;
}
//不足批的索引最后不要忘记提交
if(queries.size()>0){
restTemplate.bulkUpdate(queries);
}
restTemplate.refresh(indexName);
}
4.5数据查询
/**
*数据查询,返回List
*@paramfield查询字段
*@paramvalue查询值
*@returnList<EmployeeBean>
*/
@Override
publicList<EmployeeBean>queryMatchList(Stringfield,Stringvalue){
MatchQueryBuilderbuilder=QueryBuilders.matchQuery(field,value);
SearchQuerysearchQuery=newNativeSearchQuery(builder);
returnrestTemplate.queryForList(searchQuery,EmployeeBean.class);
}
/**
*数据查询,返回Page
*@paramfield查询字段
*@paramvalue查询值
*@returnAggregatedPage<EmployeeBean>
*/
@Override
publicAggregatedPage<EmployeeBean>queryMatchPage(Stringfield,Stringvalue){
MatchQueryBuilderbuilder=QueryBuilders.matchQuery(field,value);
SearchQuerysearchQuery=newNativeSearchQuery(builder).setPageable(PageRequest.of(0,100));
AggregatedPage<EmployeeBean>page=restTemplate.queryForPage(searchQuery,EmployeeBean.class);
longtotalElements=page.getTotalElements();//总记录数
inttotalPages=page.getTotalPages();//总页数
intpageNumber=page.getPageable().getPageNumber();//当前页号
List<EmployeeBean>beanList=page.toList();//当前页数据集
Set<EmployeeBean>beanSet=page.toSet();//当前页数据集
returnpage;
}
QueryBuilders对象是用于创建查询方法的,支持多种查询类型,常用的查询API包括以下方法:
/**
*关键字匹配查询
*
*@paramname字段的名称
*@paramvalue查询值
*/
publicstaticTermQueryBuildertermQuery(Stringname,Stringvalue){
returnnewTermQueryBuilder(name,value);
}
publicstaticTermQueryBuildertermQuery(Stringname,intvalue){
returnnewTermQueryBuilder(name,value);
}
publicstaticTermQueryBuildertermQuery(Stringname,longvalue){
returnnewTermQueryBuilder(name,value);
}
publicstaticTermQueryBuildertermQuery(Stringname,floatvalue){
returnnewTermQueryBuilder(name,value);
}
publicstaticTermQueryBuildertermQuery(Stringname,doublevalue){
returnnewTermQueryBuilder(name,value);
}
publicstaticTermQueryBuildertermQuery(Stringname,booleanvalue){
returnnewTermQueryBuilder(name,value);
}
publicstaticTermQueryBuildertermQuery(Stringname,Objectvalue){
returnnewTermQueryBuilder(name,value);
}
/**
*关键字查询,同时匹配多个关键字
*
*@paramname字段名称
*@paramvalues查询值
*/
publicstaticTermsQueryBuildertermsQuery(Stringname,String...values){
returnnewTermsQueryBuilder(name,values);
}
/**
*创建一个匹配多个关键字的查询,返回boolean
*
*@paramfieldNames字段名称
*@paramtext查询值
*/
publicstaticMultiMatchQueryBuildermultiMatchQuery(Objecttext,String...fieldNames){
returnnewMultiMatchQueryBuilder(text,fieldNames);//BOOLEANisthedefault
}
/**
*关键字,精确匹配
*
*@paramname字段名称
*@paramtext查询值
*/
publicstaticMatchQueryBuildermatchQuery(Stringname,Objecttext){
returnnewMatchQueryBuilder(name,text);
}
/**
*关键字范围查询(后面跟范围条件)
*
*@paramname字段名称
*/
publicstaticRangeQueryBuilderrangeQuery(Stringname){
returnnewRangeQueryBuilder(name);
}
/**
*判断字段是否有值
*
*@paramname字段名称
*/
publicstaticExistsQueryBuilderexistsQuery(Stringname){
returnnewExistsQueryBuilder(name);
}
/**
*模糊查询
*
*@paramname字段名称
*@paramvalue查询值
*/
publicstaticFuzzyQueryBuilderfuzzyQuery(Stringname,Stringvalue){
returnnewFuzzyQueryBuilder(name,value);
}
/**
*组合查询对象,可以同时引用上面的所有查询对象
*/
publicstaticBoolQueryBuilderboolQuery(){
returnnewBoolQueryBuilder();
}
4.6聚合查询
AggregationBuilders对象是用于创建聚合方法的,支持多种查询类型,常用的查询API包括以下方法:
/**
*根据字段聚合,统计该字段的每个值的数量
*/
publicstaticTermsAggregationBuilderterms(Stringname){
returnnewTermsAggregationBuilder(name,null);
}
/**
*统计操作的,过滤条件
*/
publicstaticFilterAggregationBuilderfilter(Stringname,QueryBuilderfilter){
returnnewFilterAggregationBuilder(name,filter);
}
/**
*设置多个过滤条件
*/
publicstaticFiltersAggregationBuilderfilters(Stringname,KeyedFilter...filters){
returnnewFiltersAggregationBuilder(name,filters);
}
/**
*统计该字段的数据总数
*/
publicstaticValueCountAggregationBuildercount(Stringname){
returnnewValueCountAggregationBuilder(name,null);
}
/**
*计算平均值
*/
publicstaticAvgAggregationBuilderavg(Stringname){
returnnewAvgAggregationBuilder(name);
}
/**
*计算最大值
*/
publicstaticMaxAggregationBuildermax(Stringname){
returnnewMaxAggregationBuilder(name);
}
/**
*计算最小值
*/
publicstaticMinAggregationBuildermin(Stringname){
returnnewMinAggregationBuilder(name);
}
/**
*计算总数
*/
publicstaticSumAggregationBuildersum(Stringname){
returnnewSumAggregationBuilder(name);
}
本文内容总结:
原文链接:https://www.cnblogs.com/huanshilang/p/14382279.html