一.【es-client】项⽬的pom.xml⽂件中,引⼊Spring Data Elasticsearch的启动器
<dependency><groupId> org.springframework.boot </groupId><artifactId> spring-boot-starter-data-elasticsearch </artifactId></dependency>
二.在resources⽬录下的application.yml⽂件中配置Elasticsearch的host和port信息
spring:data:elasticsearch:cluster-name: elasticcluster-nodes: 10.48.185.11:9301,10.48.185.93:9302,10.48.185.90:9300,10.48.185.77:9300
<!-- ES高级Rest Client --><dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId><version>6.4.3</version></dependency><dependency><groupId>org.elasticsearch</groupId><artifactId>elasticsearch</artifactId><version>6.4.3</version></dependency>
需要注意的是, Spring Data Elasticsearch 底层使⽤的不是 Elasticsearch 提供的 RestHighLevelClient ,⽽是 TransportClient,并不采⽤ HTTP 协议通信,⽽是访问 Elasticsearch 对外开放的 TCP 端⼝。我们在之前集群配置 中,设置的端⼝分别是:9301 、 9302 、 9303 。
四.测试
创建⼀个 SpringDataESTests 测试类。通过 @Autowired 注解对 ElasticsearchTemplate进⾏注⼊,测试对象是否可以获取到
package com.qff.esclient.test;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.test.context.junit4.SpringRunner;
@SpringBootTest
@RunWith(SpringRunner.class)
public class SpringDataESTests {@Autowired
private ElasticsearchTemplate template;@Testpublic void check() {System.err.println(template);}
}
如果运⾏ check() ⽅法报错,可能是以下问题所导致。
创建索引库
创建索引库需要使⽤到的注解:
package com.qff.esclient.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Document(indexName = "product",type = "product",shards = 3,replicas = 1)
public class Product {@Idprivate Long id;@Field(type = FieldType.Text, analyzer = "ik_max_word")private String title; // 标题@Field(type = FieldType.Keyword)private String category; // 分类@Field(type = FieldType.Keyword)private String brand; // 品牌@Field(type = FieldType.Double)private Double price; // 价格@Field(type = FieldType.Keyword, index = false)private String images; // 图⽚地址
}
索引数据CRUD操作(一)
在 com.yx.respository 包下⾃定义 ProductRepository 接⼝,并继承 ElasticsearchRespository 接⼝。
1.创建索引数据
单个创建
@Autowired
private ProductRepository productRepository;
@Test
public void addDocument() {Product product = new Product(1L, "⼩⽶⼿机Mix", "⼿机", "⼩⽶", 2899.00,
"http://image.yx.com/12479122.jpg");// 添加索引数据productRepository.save(product);
}
批量创建
@Test
public void addDocuments() {// 准备⽂档数据List<Product> list = new ArrayList<>();list.add(new Product(5L, "荣耀V20", "⼿机", "华为", 2799.00,
"http://image.yx.com/12479122.jpg"));// 添加索引数据productRepository.saveAll(list);
}
查询索引数据
根据 id 查询数据
查询所有数据
⾃定义⽅法查询
引数据CRUD操作(二)(原生操作)
package com.qff.esclient.sercive;
import com.google.gson.Gson;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.data.elasticsearch.core.SearchResultMapper;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/** ⾃定义查询结果映射,⽤于处理⾼亮显示 */
public class ProductSearchResultMapper implements SearchResultMapper {/*** 完成查询结果映射。将_source取出,然后放⼊⾼亮的数据*/@Overridepublic <T> AggregatedPage<T> mapResults(SearchResponse searchResponse, Class<T> aClass, Pageable pageable) {// 记录总条数long totalHits = searchResponse.getHits().getTotalHits();// 记录列表(泛型) - 构建Aggregate使⽤List<T> list = new ArrayList<>();// 获取搜索结果(真正的的记录)SearchHits hits = searchResponse.getHits();for (SearchHit hit : hits) {if (hits.getHits().length <= 0) {return null;}// 将原本的JSON对象转换成Map对象Map<String, Object> map = hit.getSourceAsMap();// 获取⾼亮的字段MapMap<String, HighlightField> highlightFields = hit.getHighlightFields();for (Map.Entry<String, HighlightField> highlightField :
highlightFields.entrySet()) {// 获取⾼亮的KeyString key = highlightField.getKey();// 获取⾼亮的ValueHighlightField value = highlightField.getValue();// 实际fragments[0]就是⾼亮的结果,⽆需遍历拼接Text[] fragments = value.getFragments();// 因为⾼亮的字段必然存在于Map中,就是key值map.put(key, fragments[0].toString());}// 把Map转换成对象Gson gson = new Gson();T item = gson.fromJson(gson.toJson(map), aClass);list.add(item);}// 返回的是带分⻚的结果return new AggregatedPageImpl<>(list, pageable, totalHits);}@Overridepublic <T> T mapSearchHit(SearchHit searchHit, Class<T> aClass) {return null;}
}
高亮自定义类
package com.qff.esclient.sercive;
import com.google.gson.Gson;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.data.elasticsearch.core.SearchResultMapper;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/** ⾃定义查询结果映射,⽤于处理⾼亮显示 */
public class ProductSearchResultMapper implements SearchResultMapper {/*** 完成查询结果映射。将_source取出,然后放⼊⾼亮的数据*/@Overridepublic <T> AggregatedPage<T> mapResults(SearchResponse searchResponse, Class<T> aClass, Pageable pageable) {// 记录总条数long totalHits = searchResponse.getHits().getTotalHits();// 记录列表(泛型) - 构建Aggregate使⽤List<T> list = new ArrayList<>();// 获取搜索结果(真正的的记录)SearchHits hits = searchResponse.getHits();for (SearchHit hit : hits) {if (hits.getHits().length <= 0) {return null;}// 将原本的JSON对象转换成Map对象Map<String, Object> map = hit.getSourceAsMap();// 获取⾼亮的字段MapMap<String, HighlightField> highlightFields = hit.getHighlightFields();for (Map.Entry<String, HighlightField> highlightField : highlightFields.entrySet()) {// 获取⾼亮的KeyString key = highlightField.getKey();// 获取⾼亮的Value tHighlightField value = highlightField.getValue();// 实际fragments[0]就是⾼亮的结果,⽆需遍历拼接Text[] fragments = value.getFragments();// 因为⾼亮的字段必然存在于Map中,就是key值map.put(key, fragments[0].toString());}// 把Map转换成对象Gson gson = new Gson();T item = gson.fromJson(gson.toJson(map), aClass);list.add(item);}// 返回的是带分⻚的结果return new AggregatedPageImpl<>(list, pageable, totalHits);}@Overridepublic <T> T mapSearchHit(SearchHit searchHit, Class<T> aClass) {return null;}
}