Springboot整合ElasticSearch采用RestHighClient的方式 | 代码搬运工
添加依赖首先需要创建SpringBoot项目,并在项目的pom.xml文件中添加如下依赖:
添加配置UTF-8 UTF-8 1.8 true org.springframework.boot spring-boot-starter-parent2.0.4.RELEASE org.springframework.boot spring-boot-starter-weborg.elasticsearch.client elasticsearch-rest-high-level-client6.6.0 org.elasticsearch elasticsearch6.6.0 org.projectlombok lombok1.18.0 com.alibaba fastjson1.2.60 commons-lang commons-lang2.6
在resources目录下创建application.yml配置文件,配置如下:
spring: application: name: springboot-es elasticsearch: host: 192.168.192.11 port: 9200 schema: http index: number-of-shards: 3 number-of-replicas: 1具体实现
ElasticsearchRestClient.java代码如下:
@Configuration public class ElasticsearchRestClient { @Value("${elasticsearch.host}") private String esHost; @Value("${elasticsearch.port}") private int esPort; @Bean public RestClientBuilder restClientBuilder() { return RestClient.builder(new HttpHost(esHost, esPort, "http")); } @Bean public RestHighLevelClient highLevelClient(@Autowired RestClientBuilder restClientBuilder) { restClientBuilder.setMaxRetryTimeoutMillis(60000); return new RestHighLevelClient(restClientBuilder); } }
Item.java代码如下:
@Slf4j @Data @Builder @NoArgsConstructor @AllArgsConstructor public class Item { // ES主键 private String _id; // 数据库主键 private Long id; //标题 private String title; // 分类 private String category; // 品牌 private String brand; // 价格 private Double price; // 图片地址 private String images; public static XContentBuilder buildMapping (){ XContentBuilder builder = null; try { builder = JsonXContent.contentBuilder() .startObject() .startObject("properties") .startObject("id") .field("type", "long") .field("index", "true") .endObject() .startObject("title") .field("type", "text") .field("index", "true") .field("analyzer", "ik_max_word") .endObject() .startObject("category") .field("type", "keyword") .field("index", "true") .endObject() .startObject("brand") .field("type", "keyword") .field("index", "true") .endObject() .startObject("price") .field("type", "double") .field("index", "true") .endObject() .startObject("images") .field("type", "keyword") .field("index", "true") .endObject() .endObject() .endObject(); } catch (IOException e) { log.error(e.getMessage(), e); } return builder; } }
ik 带有两个分词器:
ik_max_word:会将文本做最细粒度的拆分;尽可能多的拆分出词语ik_smart:会做最粗粒度的拆分;已被分出的词语将不会再次被其它词语占有
EsCurdService.java代码如下:
public interface EsCurdService { public void createIndex(String indexName); public void createIndex(String indexName, String type, XContentBuilder builder); public boolean existIndex(String indexName); public void deleteIndex(String indexName); public RestStatus insert(String indexName, String type, Object object); public RestStatus update(String indexName, String type, String id, Object object); public RestStatus delete(String indexName, String type, String id); public SearchResponse search(String indexName, String type, SearchSourceBuilder builder); }
EsCurdServiceImpl.java代码如下:
@Slf4j @Service public class EsCurdServiceImpl implements EsCurdService { @Value("${elasticsearch.index.number-of-shards:3}") private int number_of_shards; @Value("${elasticsearch.index.number-of-replicas:2}") private int number_of_replicas; @Autowired private RestHighLevelClient highLevelClient; @Override public void createIndex(String indexName) { // 判断是否存在索引 if(existIndex(indexName)) { return; } // 创建索引 CreateIndexRequest createIndexRequest = new CreateIndexRequest(); createIndexRequest.index(indexName).settings(Settings.builder() // 分片数 .put("index.number_of_shards", number_of_shards) // 备份数 .put("index.number_of_replicas", number_of_replicas)); CreateIndexResponse response = null; try { response = highLevelClient.indices().create(createIndexRequest, RequestOptions.DEFAULT); } catch (IOException e) { log.info(e.getMessage(), e); } } @Override public void createIndex(String indexName, String type, XContentBuilder builder) { // 判断是否存在索引 if(existIndex(indexName)) { return; } // 创建索引 CreateIndexRequest createIndexRequest = new CreateIndexRequest(); createIndexRequest.index(indexName).settings(Settings.builder() // 分片数 .put("index.number_of_shards", number_of_shards) // 备份数 .put("index.number_of_replicas", number_of_replicas)) // 创建映射 .mapping(type, builder); CreateIndexResponse response = null; try { response = highLevelClient.indices().create(createIndexRequest, RequestOptions.DEFAULT); } catch (IOException e) { log.info(e.getMessage(), e); } } @Override public boolean existIndex(String indexName) { // 判断索引是否存在 boolean isExist = false; GetIndexRequest getIndexRequest = new GetIndexRequest(); getIndexRequest.indices(indexName); try { isExist = highLevelClient.indices().exists(getIndexRequest, RequestOptions.DEFAULT); } catch (IOException e) { log.info(e.getMessage(), e); } return isExist; } @Override public void deleteIndex(String indexName) { DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest(); deleteIndexRequest.indices(indexName); try { highLevelClient.indices().delete(deleteIndexRequest, RequestOptions.DEFAULT); } catch (IOException e) { log.info(e.getMessage(), e); } } @Override public RestStatus insert(String indexName, String type, Object object) { IndexRequest indexRequest = new IndexRequest(); // source方法里面需要填写对应数据的类型,默认数据类型为json indexRequest.index(indexName).type(type).source(JSON.toJSonString(object), XContentType.JSON); IndexResponse response = null; try { response = highLevelClient.index(indexRequest, RequestOptions.DEFAULT); return response.status(); } catch (IOException e) { log.info(e.getMessage(), e); } return null; } @Override public RestStatus update(String indexName, String type, String id, Object object) { UpdateRequest request = new UpdateRequest(); request.index(indexName).type(type).id(id).doc(JSON.toJSonString(object), XContentType.JSON); UpdateResponse response = null; try { response = highLevelClient.update(request, RequestOptions.DEFAULT); return response.status(); } catch (IOException e) { log.info(e.getMessage(), e); } return null; } @Override public RestStatus delete(String indexName, String type, String id) { DeleteRequest request = new DeleteRequest(); request.index(indexName).type(type).id(id); DeleteResponse response = null; try { response = highLevelClient.delete(request, RequestOptions.DEFAULT); return response.status(); } catch (IOException e) { log.info(e.getMessage(), e); } return null; } @Override public SearchResponse search(String indexName, String type, SearchSourceBuilder sourceBuilder) { SearchRequest searchRequest = new SearchRequest(); searchRequest.indices(indexName).types(type).source(sourceBuilder); SearchResponse response = null; try { response = highLevelClient.search(searchRequest, RequestOptions.DEFAULT); return response; } catch (IOException e) { log.info(e.getMessage(), e); } return null; } }
IndexController.java代码如下:
@Slf4j @RestController @RequestMapping("/es") public class IndexController { @Autowired private EsCurdService esCurdService; // es索引(相当于数据库) public static final String ES_INDEX_NAME = "es-index"; // es文档类型(相当于库表) public static final String ES_DOC_TYPE = "item"; @GetMapping("/add") public void create(){ Item item = Item.builder() .id(1L) .title("小米手机7") .category("手机") .brand("小米") .images("http://image.leyou.com/13123.jpg") .build(); XContentBuilder builder = Item.buildMapping(); esCurdService.createIndex(ES_INDEX_NAME, ES_DOC_TYPE, builder); esCurdService.insert(ES_INDEX_NAME, ES_DOC_TYPE, item); } @GetMapping("/update") public void update(){ Item item = Item.builder() .id(1L) .title("小米手机8") .category("手机") .brand("小米") .images("http://image.leyou.com/13123.jpg") .build(); String _id = "RsBwNHQBWruqdhIY3dgZ"; esCurdService.update(ES_INDEX_NAME, ES_DOC_TYPE, _id, item); } @GetMapping("/list") public List- list(){ SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); // 分页参数 sourceBuilder.from(0); sourceBuilder.size(10); BoolQueryBuilder boolBuilder = QueryBuilders.boolQuery(); // 关键词查找匹配,这个不是精确查找,他会对字段中的内容进行切词匹配 MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("title", "小米"); boolBuilder.must(matchQueryBuilder); // 设置需要返回的字段 sourceBuilder.fetchSource(new String[]{"id", "title", "category"}, new String[]{}).query(boolBuilder); // 高亮 HighlightBuilder highlightBuilder = new HighlightBuilder(); highlightBuilder.preTags(""); //前置元素 highlightBuilder.postTags(""); //后置元素 highlightBuilder.fields().add(new HighlightBuilder.Field("title")); //高亮查询字段 highlightBuilder.requireFieldMatch(false); //如果要多个字段高亮,这项要为false sourceBuilder.highlighter(highlightBuilder); SearchResponse response = esCurdService.search(ES_INDEX_NAME, ES_DOC_TYPE, sourceBuilder); ObjectMapper objectMapper = new ObjectMapper(); List
- result = new ArrayList<>(); response.getHits().iterator().forEachRemaining(hit -> { Map
highlightFields = hit.getHighlightFields(); HighlightField content = highlightFields.get("title"); //fragments就是高亮显示的片段 Text[] fragments = content.fragments(); StringBuffer sb = new StringBuffer(); //拼接查询出来的高亮片段 for (Text text:fragments){ sb.append(text); } //将查询结果转化为对象--因为我们要进行替换,所以要转化成对象,然后直接将高亮片段替换原有对象内容 try { Item item = objectMapper.readValue(hit.getSourceAsString() , Item.class); // 设置ES中主键 item.set_id(hit.getId()); //开始进行高亮替换 if(StringUtils.isNotEmpty(sb.toString())) { item.setTitle(sb.toString()); } result.add(item); } catch (IOException e) { log.error(e.getMessage(), e); } }); return result; } }
注意: 使用es存储日志,index按天切割,查询时索引库可以用通配符*,例如用es-*查询所有匹配索引中数据
本文代码git地址 GitHub - chaojunma/springboot-es: Springboot整合ElasticSearch采用RestHighClient的方式
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)