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