国外手做网站,免费创建网站平台有哪些,软件项目管理工具,wordpress的栏目页关键词怎么设置开源框架springboot框架中集成es。使用org.springframework.data.elasticsearch下的依赖,实现对elasticsearch的CURD,非常方便#xff0c;但是springboot和elasticsearch版本对应很严格#xff0c;对应版本不统一启动会报错。 文章目录开源框架Elasticsearch 7.x安装Elastics… 开源框架springboot框架中集成es。使用org.springframework.data.elasticsearch下的依赖,实现对elasticsearch的CURD,非常方便但是springboot和elasticsearch版本对应很严格对应版本不统一启动会报错。 文章目录开源框架Elasticsearch 7.x安装Elasticsearch和springboot版本对应配置elasticSearch测试类springframework实现对象操作eses实体对象es接口AbstractResultMapperMapperServiceServiceImpl开源框架
开源框架
Elasticsearch 7.x安装
Elasticsearch 7.x 安装步骤
dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-elasticsearch/artifactId
/dependency注意 springboot集成的elasticSearch的版本可能和 我们自己使用的不一致可能会导致项目报错需要手动把版本 改成和我们使用的一致
版本不一致异常信息
Elasticsearch和springboot版本对应
Elasticsearch和springboot版本对应
springboot 2.1.6 对应 Elasticsearch 6.3.2
springboot 2.2.5 对应 Elasticsearch 7.6.0
springboot 2.2.6 对应 Elasticsearch 7.7.0配置elasticSearch
Configuration
public class ESClient {Beanpublic RestHighLevelClient restHighLevelClient(){RestHighLevelClient client new RestHighLevelClient(RestClient.builder(new HttpHost(127.0.0.1,9200,http)));return client;}
}
测试类
SpringBootTest
class EstestApplicationTests {AutowiredQualifier(restHighLevelClient)private RestHighLevelClient client;//测试创建索引库Testvoid createIndex() throws IOException {//创建请求CreateIndexRequest request new CreateIndexRequest(test1);//执行请求CreateIndexResponse response client.indices().create(request, RequestOptions.DEFAULT);System.out.println(response.toString());//org.elasticsearch.client.indices.CreateIndexResponse6a5dc7e}//查看索引库是否存在 true存在false不存在Testvoid existsIndex() throws IOException {//创建请求GetIndexRequest request new GetIndexRequest(test1);boolean exists client.indices().exists(request, RequestOptions.DEFAULT);System.out.println(exists);}//删除索引库Testvoid deleteIndex() throws IOException {DeleteIndexRequest request new DeleteIndexRequest(test1);AcknowledgedResponse delete client.indices().delete(request, RequestOptions.DEFAULT);//删除成功返回true失败返回falseSystem.out.println(delete.isAcknowledged());}//文档操作//添加文档Testvoid createDocument() throws IOException {//创建添加数据User user new User(张三,23);//声明要保存到那个索引库IndexRequest request new IndexRequest(test1);request.id(1).timeout(1s);//给请求放入数据request.source(JSON.toJSONString(user), XContentType.JSON);//执行请求IndexResponse resp client.index(request, RequestOptions.DEFAULT);System.out.println(resp);System.out.println(resp.status());//CREATED}//修改文档Testvoid updateDocument() throws IOException {//声明修改数据//User user new User(李四,20);User user new User();user.setName(王五);//声明索引库UpdateRequest request new UpdateRequest(test1,1);//设置修改的文档id和请求超时时间request.id(1).timeout(1s);request.doc(JSON.toJSONString(user),XContentType.JSON);//执行修改 修改的时候如果对象中某个字段没有给值那么也会修改成默认值UpdateResponse update client.update(request,RequestOptions.DEFAULT);System.out.println(update);System.out.println(update.status());//ok}//查看文档是否存在Testvoid existsDocument() throws IOException {GetRequest request new GetRequest(test1,1);boolean exists client.exists(request, RequestOptions.DEFAULT);//存在返回true不存在返回falseSystem.out.println(exists);}//删除文档Testvoid deleteDocument() throws IOException {DeleteRequest request new DeleteRequest(test1,1);DeleteResponse delete client.delete(request, RequestOptions.DEFAULT);System.out.println(delete);System.out.println(delete.status());//ok}//根据id获取文档Testvoid getDocument() throws IOException {GetRequest request new GetRequest(test1,1);GetResponse resp client.get(request, RequestOptions.DEFAULT);System.out.println(resp);//获取文档内容的字符串没有数据为nullSystem.out.println(resp.getSourceAsString());}//批量操作,修改和删除操作只是改变request即可Testvoid bulkadd() throws IOException {BulkRequest bulkRequest new BulkRequest();bulkRequest.timeout(10s);ListUser list new ArrayList();list.add(new User(chen1,20));list.add(new User(chen2,20));list.add(new User(chen3,20));list.add(new User(chen4,20));list.add(new User(chen5,20));list.add(new User(chen6,20));list.add(new User(chen7,20));list.add(new User(chen8,20));//注意id要是重复则会覆盖掉for (int i 0; i list.size(); i) {bulkRequest.add(new IndexRequest(test1).id((i1)).source(JSON.toJSONString(list.get(i)),XContentType.JSON));}//执行BulkResponse bulk client.bulk(bulkRequest, RequestOptions.DEFAULT);System.out.println(bulk);System.out.println(bulk.status());}//条件查询文档Testvoid searchDocument() throws IOException {//声明请求SearchRequest request new SearchRequest(test1);//创建查询构造器对象SearchSourceBuilder builder new SearchSourceBuilder();//精准查询条件构造器还可以封装很多的构造器,都可以使用QueryBuilders这个类构建//QueryBuilders里面封装了我们使用的所有查询筛选命令TermQueryBuilder termQueryBuilder QueryBuilders.termQuery(name, chen1);//把查询条件构造器放入到查询构造器中builder.query(termQueryBuilder);//把条件构造器放入到请求中request.source(builder);//执行查询SearchResponse search client.search(request, RequestOptions.DEFAULT);//这个查询就和我们使用命令返回的结果是一致的System.out.println(JSON.toJSONString(search.getHits().getHits()));for (SearchHit hit : search.getHits().getHits()) {//遍历获取到的hits让每一个hit封装为map形式System.out.println(hit.getSourceAsMap());}}
}springframework实现对象操作es
es实体对象 org.springframework.data.annotation.Id; org.springframework.data.elasticsearch.annotations.Document; org.springframework.data.elasticsearch.annotations.Field; org.springframework.data.elasticsearch.annotations.FieldType; Document(indexName bookinfosearch, type bookinfo)
public class BookInfoSearch implements Serializable {private static final long serialVersionUID 1L;// 必须指定一个idIdprivate String id;// 这里配置了分词器字段类型可以不配置默认也可// 名称Field(type FieldType.Text, analyzer ik_max_word)private String name;// 简称Field(type FieldType.Text, analyzer ik_max_word)private String bookName;//书本版本号private BigDecimal currentVersion;//书本首字母Field(type FieldType.Keyword)private String initials;//操作类型add update deleteField(type FieldType.Keyword)private String type;//书本分类信息的聚合体private ListString tagJson;//分类IdField(type FieldType.Keyword)private ListString tagIds; //集合 1,2,3//分类名称Field(type FieldType.Keyword)private ListString tagNames;//属性集合Field(type FieldType.Text, analyzer ik_smart)private ListString attributes;//创建时间private Date createTime;//更新时间private Date updateTime;public String getId() {return id;}public void setId(String id) {this.id id;}public String getName() {return name;}public void setName(String name) {this.name name;}public BigDecimal getCurrentVersion() {return currentVersion;}public void setCurrentVersion(BigDecimal currentVersion) {this.currentVersion currentVersion;}public String getInitials() {return initials;}public void setInitials(String initials) {this.initials initials;}public String getType() {return type;}public void setType(String type) {this.type type;}public ListString getTagIds() {return tagIds;}public void setTagIds(ListString tagIds) {this.tagIds tagIds;}public ListString getTagNames() {return tagNames;}public void setTagNames(ListString tagNames) {this.tagNames tagNames;}public ListString getAttributes() {return attributes;}public void setAttributes(ListString attributes) {this.attributes attributes;}public Date getCreateTime() {return createTime;}public void setCreateTime(Date createTime) {this.createTime createTime;}public Date getUpdateTime() {return updateTime;}public void setUpdateTime(Date updateTime) {this.updateTime updateTime;}
}
es接口 org.springframework.data.repository.CrudRepository public interface KgInfoSearchMapper extends CrudRepositoryKgInfoSearch, String {
}AbstractResultMapper 类抽象结果映射器 org.springframework.data.elasticsearch.core java.lang.Object org.springframework.data.elasticsearch.core.AbstractResultMapper 所有已实现的接口 GetResultMapperMultiGetResultMapperResultMapperSearchResultMapper 构造函数和描述
AbstractResultMapper(EntityMapper entityMapper) 全部方法
EntityMapper getEntityMapper()
T T mapEntity(String source, ClassT clazz) public abstract class AbstractResultMapper implements ResultsMapper {private EntityMapper entityMapper;public AbstractResultMapper(EntityMapper entityMapper) {Assert.notNull(entityMapper, EntityMapper must not be null!);this.entityMapper entityMapper;}public T T mapEntity(String source, ClassT clazz) {if (StringUtils.isEmpty(source)) {return null;} else {try {return this.entityMapper.mapToObject(source, clazz);} catch (IOException var4) {throw new ElasticsearchException(failed to map source [ source ] to class clazz.getSimpleName(), var4);}}}public EntityMapper getEntityMapper() {return this.entityMapper;}
}Mapper org.springframework.data.elasticsearch Component
public class MyResultMapper extends AbstractResultMapper {private final MappingContext? extends ElasticsearchPersistentEntity?, ElasticsearchPersistentProperty mappingContext;public MyResultMapper() {this(new SimpleElasticsearchMappingContext());}public MyResultMapper(MappingContext? extends ElasticsearchPersistentEntity?, ElasticsearchPersistentProperty mappingContext) {super(new DefaultEntityMapper(mappingContext));Assert.notNull(mappingContext, MappingContext must not be null!);this.mappingContext mappingContext;}public MyResultMapper(EntityMapper entityMapper) {this(new SimpleElasticsearchMappingContext(), entityMapper);}public MyResultMapper(MappingContext? extends ElasticsearchPersistentEntity?, ElasticsearchPersistentProperty mappingContext,EntityMapper entityMapper) {super(entityMapper);Assert.notNull(mappingContext, MappingContext must not be null!);this.mappingContext mappingContext;}Overridepublic T AggregatedPageT mapResults(SearchResponse response, ClassT clazz, Pageable pageable) {long totalHits response.getHits().getTotalHits();float maxScore response.getHits().getMaxScore();ListT results new ArrayList();for (SearchHit hit : response.getHits()) {if (hit ! null) {T result null;if (!StringUtils.isEmpty(hit.getSourceAsString())) {result mapEntity(hit.getSourceAsString(), clazz);} else {result mapEntity(hit.getFields().values(), clazz);}setPersistentEntityId(result, hit.getId(), clazz);setPersistentEntityVersion(result, hit.getVersion(), clazz);setPersistentEntityScore(result, hit.getScore(), clazz);populateScriptFields(result, hit);results.add(result);}}return new AggregatedPageImplT(results, pageable, totalHits, response.getAggregations(), response.getScrollId(),maxScore);}private String concat(Text[] texts) {StringBuilder sb new StringBuilder();for (Text text : texts) {sb.append(text.toString());}return sb.toString();}private T void populateScriptFields(T result, SearchHit hit) {if (hit.getFields() ! null !hit.getFields().isEmpty() result ! null) {for (java.lang.reflect.Field field : result.getClass().getDeclaredFields()) {ScriptedField scriptedField field.getAnnotation(ScriptedField.class);if (scriptedField ! null) {String name scriptedField.name().isEmpty() ? field.getName() : scriptedField.name();DocumentField searchHitField hit.getFields().get(name);if (searchHitField ! null) {field.setAccessible(true);try {field.set(result, searchHitField.getValue());} catch (IllegalArgumentException e) {throw new ElasticsearchException(failed to set scripted field: name with value: searchHitField.getValue(), e);} catch (IllegalAccessException e) {throw new ElasticsearchException(failed to access scripted field: name, e);}}}}}for (HighlightField field : hit.getHighlightFields().values()) {try {PropertyUtils.setProperty(result, field.getName(), concat(field.fragments()));} catch (InvocationTargetException | IllegalAccessException | NoSuchMethodException e) {throw new ElasticsearchException(failed to set highlighted value for field: field.getName() with value: Arrays.toString(field.getFragments()), e);}}}private T T mapEntity(CollectionDocumentField values, ClassT clazz) {return mapEntity(buildJSONFromFields(values), clazz);}private String buildJSONFromFields(CollectionDocumentField values) {JsonFactory nodeFactory new JsonFactory();try {ByteArrayOutputStream stream new ByteArrayOutputStream();JsonGenerator generator nodeFactory.createGenerator(stream, JsonEncoding.UTF8);generator.writeStartObject();for (DocumentField value : values) {if (value.getValues().size() 1) {generator.writeArrayFieldStart(value.getName());for (Object val : value.getValues()) {generator.writeObject(val);}generator.writeEndArray();} else {generator.writeObjectField(value.getName(), value.getValue());}}generator.writeEndObject();generator.flush();return new String(stream.toByteArray(), Charset.forName(UTF-8));} catch (IOException e) {return null;}}Overridepublic T T mapResult(GetResponse response, ClassT clazz) {T result mapEntity(response.getSourceAsString(), clazz);if (result ! null) {setPersistentEntityId(result, response.getId(), clazz);setPersistentEntityVersion(result, response.getVersion(), clazz);}return result;}Overridepublic T LinkedListT mapResults(MultiGetResponse responses, ClassT clazz) {LinkedListT list new LinkedList();for (MultiGetItemResponse response : responses.getResponses()) {if (!response.isFailed() response.getResponse().isExists()) {T result mapEntity(response.getResponse().getSourceAsString(), clazz);setPersistentEntityId(result, response.getResponse().getId(), clazz);setPersistentEntityVersion(result, response.getResponse().getVersion(), clazz);list.add(result);}}return list;}private T void setPersistentEntityId(T result, String id, ClassT clazz) {if (clazz.isAnnotationPresent(Document.class)) {ElasticsearchPersistentEntity? persistentEntity mappingContext.getRequiredPersistentEntity(clazz);ElasticsearchPersistentProperty idProperty persistentEntity.getIdProperty();// Only deal with String because ES generated Ids are strings !if (idProperty ! null idProperty.getType().isAssignableFrom(String.class)) {persistentEntity.getPropertyAccessor(result).setProperty(idProperty, id);}}}private T void setPersistentEntityVersion(T result, long version, ClassT clazz) {if (clazz.isAnnotationPresent(Document.class)) {ElasticsearchPersistentEntity? persistentEntity mappingContext.getPersistentEntity(clazz);ElasticsearchPersistentProperty versionProperty persistentEntity.getVersionProperty();// Only deal with Long because ES versions are longs !if (versionProperty ! null versionProperty.getType().isAssignableFrom(Long.class)) {// check that a version was actually returned in the response, -1 would indicate that// a search didnt request the version ids in the response, which would be an issueAssert.isTrue(version ! -1, Version in response is -1);persistentEntity.getPropertyAccessor(result).setProperty(versionProperty, version);}}}private T void setPersistentEntityScore(T result, float score, ClassT clazz) {if (clazz.isAnnotationPresent(Document.class)) {ElasticsearchPersistentEntity? entity mappingContext.getRequiredPersistentEntity(clazz);if (!entity.hasScoreProperty()) {return;}entity.getPropertyAccessor(result) //.setProperty(entity.getScoreProperty(), score);}}
}Service /*** 查询* param bookInfoSearchQueryParam 和实体对象字段一样* return*/PageEsResult searchInfoByBookName(BookInfoSearchQueryParam bookInfoSearchQueryParam);ServiceImpl
Overridepublic PageEsResult searchInfoByBookName(BookInfoSearchQueryParam bookInfoSearchQueryParam) {BoolQueryBuilder queryBuilder QueryBuilders.boolQuery();//1. 创建一个查询条件对象if (bookInfoSearchQueryParam ! null ObjectUtil.isNotEmpty(bookInfoSearchQueryParam.getKey())) {String key bookInfoSearchQueryParam.getKey();key QueryParser.escape(key);MultiMatchQueryBuilder matchQueryBuilder QueryBuilders// 匹配多个字段 关键字 名称.multiMatchQuery(key, name).analyzer(ik_max_word).field(name, 0.1f);queryBuilder.must(matchQueryBuilder);}if (bookInfoSearchQueryParam ! null ObjectUtil.isNotEmpty(bookInfoSearchQueryParam.getTagId())) {queryBuilder.must(QueryBuilders.termQuery(tagIds, bookInfoSearchQueryParam.getTagId()));}//2.创建聚合查询TermsAggregationBuilder agg null;if (bookInfoSearchQueryParam ! null ObjectUtil.isNotEmpty(bookInfoSearchQueryParam.getAgg())) {agg AggregationBuilders.terms(bookInfoSearchQueryParam.getAgg()).field(bookInfoSearchQueryParam.getAgg() .keyword).size(Integer.MAX_VALUE);;//keyword表示不使用分词进行聚合}String sortField ;if (bookInfoSearchQueryParam ! null ObjectUtil.isNotEmpty(bookInfoSearchQueryParam.getSortField())) {sortField bookInfoSearchQueryParam.getSortField();}String sortRule ;if (bookInfoSearchQueryParam ! null ObjectUtil.isNotEmpty(bookInfoSearchQueryParam.getSortRule())) {sortRule bookInfoSearchQueryParam.getSortRule();}NativeSearchQueryBuilder nativeSearchQueryBuilder new NativeSearchQueryBuilder();nativeSearchQueryBuilder.withTypes(bookinfo); // 类型nativeSearchQueryBuilder.withIndices(bookinfosearch);//索引nativeSearchQueryBuilder.withQuery(queryBuilder); //添加查询条件if (agg ! null) {nativeSearchQueryBuilder.addAggregation(agg);}if (bookInfoSearchQueryParam ! null ObjectUtil.isNotEmpty(bookInfoSearchQueryParam.getKey())) {HighlightBuilder.Field field new HighlightBuilder.Field(name).preTags(font stylecolor:red).postTags(/font);HighlightBuilder.Field fieldAttributes new HighlightBuilder.Field(attributes).preTags(font stylecolor:red).postTags(/font);field.fragmentSize(500);nativeSearchQueryBuilder.withHighlightFields(field, fieldAttributes);}nativeSearchQueryBuilder.withPageable(PageRequest.of(bookInfoSearchQueryParam.getPage(), bookInfoSearchQueryParam.getPageSize())); //符合查询条件的文档分页不是聚合的分页if (ObjectUtil.isNotEmpty(sortField) ObjectUtil.isNotEmpty(sortRule)) {nativeSearchQueryBuilder.withSort(SortBuilders.fieldSort(sortField).order(SortOrder.valueOf(sortRule)));}NativeSearchQuery build nativeSearchQueryBuilder.build();// 执行查询AggregatedPageKgInfoSearch testEntities elasticsearchTemplate.queryForPage(build, BookInfoSearch.class, myResultMapper);// 取出聚合结果ggregations entitiesAggregations testEntities.getAggregations();Terms terms (Terms) entitiesAggregations.asMap().get(bookInfoSearchQueryParam.getAgg());// 遍历取出聚合字段列的值与对应的数量if (terms ! null terms.getBuckets() ! null terms.getBuckets().size() 0) {for (Terms.Bucket bucket : terms.getBuckets()) {String keyAsString bucket.getKeyAsString(); // 聚合字段列的值long docCount bucket.getDocCount();// 聚合字段对应的数量log.info(keyAsString{},value{}, keyAsString, docCount);list集合.add(keyAsString);}}//搜索数据保存搜索历史JSONObject jsonObject new JSONObject();jsonObject.put(key, bookInfoSearchQueryParam.getKey());jsonObject.put(key, bookInfoSearchQueryParam.getKey());return 接收result;}请求参数Param对象 在es实体对象基础上 添加搜索条件字段 private String sortField; //排序字段 时间:updateTime /字母:initialsprivate String sortRule; //sortRule 排序规则 - 顺序(ASC)/倒序(DESC)private boolean allQuery false;//是否全部查询private String agg;//聚类查询字段名称private String sessionId;private int pageSize 10;private int page 0;