1. 在 pom.xml 准备依赖
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
2. 在 application.proporties 配置地址
spring.elasticsearch.rest.uris=http://192.168.56.129:9200
3. 准备 Product 类
@AllArgsConstructor
@NoArgsConstructor
@ToString
@Data
@Document(indexName = "product", shards = 3, replicas = 2) //shards:分片数量,replicas:副本数量
public class Product {
@Id
private Long id;
@Field(type = FieldType.Text, analyzer = "ik_max_word")
private String title;
@Field(type = FieldType.Keyword, index = false)
private String images;
@Field(type = FieldType.Double)
private Double price;
@Field(type = FieldType.Keyword)
private String brand;
@Field(type = FieldType.Keyword)
private String category;
}
4. ElasticsearchRestTemplate 使用
@SpringBootTest
class EsDemoProductTests {
// ElasticsearchTemplate是TransportClient客户端 已过期
// ElasticsearchRestTemplate是RestHighLevel客户端
@Autowired
private ElasticsearchRestTemplate restTemplate;
//创建产品索引库
@Test
void testCreateProduct() {
// 索引库操作对象
IndexOperations indexOps = this.restTemplate.indexOps(Product.class);
indexOps.create(); // 初始化索引库
indexOps.putMapping(indexOps.createMapping(Product.class)); // 声明映射
}
@Test
void testDocument() {
this.restTemplate.save(
new Product(1L, "小米手机", "http://xiaomi.com/xm.jpg", 2999D, "小米", "手机"),
new Product(2L, "大米手机", "http://xiaomi.com/xm.jpg", 3999D, "小米", "手机"),
new Product(3L, "红米手机", "http://xiaomi.com/xm.jpg", 1999D, "小米", "手机"),
new Product(4L, "炒米手机", "http://xiaomi.com/xm.jpg", 999D, "小米", "手机"),
new Product(5L, "华为手机", "http://xiaomi.com/xm.jpg", 3999D, "华为", "手机"),
new Product(6L, "荣耀手机", "http://xiaomi.com/xm.jpg", 2599D, "华为", "手机"),
new Product(7L, "oppo手机", "http://xiaomi.com/xm.jpg", 2399D, "oppo", "手机"),
new Product(8L, "vivo手机", "http://xiaomi.com/xm.jpg", 2599D, "vivo", "手机"),
new Product(9L, "小米电视", "http://xiaomi.com/xm.jpg", 2799D, "小米", "电视"),
new Product(10L, "小米笔记本", "http://xiaomi.com/xm.jpg", 4999D, "小米", "笔记本"),
new Product(11L, "华为笔记本", "http://xiaomi.com/xm.jpg", 5999D, "华为", "笔记本")
);
// this.restTemplate.delete("1", Product.class);
}
@Test
void testSearch() {
// 自定义搜索条件构建器
NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
// 构建器中添加匹配搜索条件
queryBuilder.withQuery(QueryBuilders.matchQuery("title", "小米手机").operator(Operator.OR));
// 添加过滤条件
queryBuilder.withFilter(QueryBuilders.rangeQuery("price").gte(1999).lte(3999));
// 排序
queryBuilder.withSort(SortBuilders.fieldSort("price").order(SortOrder.DESC));
// 分页:页码从0开始
queryBuilder.withPageable(PageRequest.of(2, 3));
// 高亮
queryBuilder.withHighlightBuilder(new HighlightBuilder().field("title").preTags("<em>").postTags("</em>"));
// 结果集过滤
queryBuilder.withSourceFilter(new FetchSourceFilter(new String[]{"title", "images", "price"}, null));
// 聚合
queryBuilder.addAggregation(AggregationBuilders.terms("brandAgg").field("brand"));
// 执行搜索,获取搜索结果集
SearchHits<Product> searchHits = this.restTemplate.search(queryBuilder.build(), Product.class);
System.out.println("总命中数:" + searchHits.getTotalHits());
// 当前页的记录
List<SearchHit<Product>> hits = searchHits.getSearchHits();
System.out.println("===================文档内容=======================");
hits.forEach(hit -> {
Product product = hit.getContent();
System.out.println("高亮前:" + product);
List<String> titles = hit.getHighlightField("title");
product.setTitle(titles.get(0));
System.out.println("高亮后:" + product);
System.out.println("-----------------------------------");
});
// 聚合结果集解析
System.out.println("===================聚合结果集=======================");
Aggregations aggregations = searchHits.getAggregations();
ParsedStringTerms brandAgg = aggregations.get("brandAgg");
brandAgg.getBuckets().forEach(bucket -> {
System.out.println("桶名称:" + bucket.getKeyAsString());
System.out.println("文档数量:" + bucket.getDocCount());
System.out.println("--------------------------");
});
}
}
5. RestHighLevelClient 使用
@SpringBootTest
class EsDemoProductTests {
@Autowired
private RestHighLevelClient restHighLevelClient;
private static final ObjectMapper MAPPER = new ObjectMapper();
//创建产品索引库
@Test
void testCreateProduct() {
// 索引库操作对象
IndexOperations indexOps = this.restTemplate.indexOps(Product.class);
indexOps.create(); // 初始化索引库
indexOps.putMapping(indexOps.createMapping(Product.class)); // 声明映射
}
@Test
void testDocument() {
this.restTemplate.save(
new Product(1L, "小米手机", "http://xiaomi.com/xm.jpg", 2999D, "小米", "手机"),
new Product(2L, "大米手机", "http://xiaomi.com/xm.jpg", 3999D, "小米", "手机"),
new Product(3L, "红米手机", "http://xiaomi.com/xm.jpg", 1999D, "小米", "手机"),
new Product(4L, "炒米手机", "http://xiaomi.com/xm.jpg", 999D, "小米", "手机"),
new Product(5L, "华为手机", "http://xiaomi.com/xm.jpg", 3999D, "华为", "手机"),
new Product(6L, "荣耀手机", "http://xiaomi.com/xm.jpg", 2599D, "华为", "手机"),
new Product(7L, "oppo手机", "http://xiaomi.com/xm.jpg", 2399D, "oppo", "手机"),
new Product(8L, "vivo手机", "http://xiaomi.com/xm.jpg", 2599D, "vivo", "手机"),
new Product(9L, "小米电视", "http://xiaomi.com/xm.jpg", 2799D, "小米", "电视"),
new Product(10L, "小米笔记本", "http://xiaomi.com/xm.jpg", 4999D, "小米", "笔记本"),
new Product(11L, "华为笔记本", "http://xiaomi.com/xm.jpg", 5999D, "华为", "笔记本")
);
// this.restTemplate.delete("1", Product.class);
}
@Test
void testRestSearch() throws IOException {
SearchRequest request = new SearchRequest();
request.indices("product");
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
boolQuery.must(QueryBuilders.matchQuery("title", "小米手机").operator(Operator.OR));
boolQuery.filter(QueryBuilders.rangeQuery("price").gte(1999).lte(3999));
sourceBuilder.query(boolQuery);
sourceBuilder.sort("price", SortOrder.DESC);
sourceBuilder.from(6);
sourceBuilder.size(3);
sourceBuilder.highlighter(new HighlightBuilder().field("title").preTags("<em>").postTags("</em>"));
sourceBuilder.fetchSource(new String[]{"title", "images", "price"}, null);
sourceBuilder.aggregation(AggregationBuilders.terms("brandAgg").field("brand"));
System.out.println("sourceBuilder = " + sourceBuilder);
request.source(sourceBuilder);
SearchResponse response = this.restHighLevelClient.search(request, RequestOptions.DEFAULT);
System.out.println("response = " + response);
org.elasticsearch.search.SearchHits searchHits = response.getHits();
System.out.println("总命中数:" + searchHits.getTotalHits().value);
org.elasticsearch.search.SearchHit[] hitsHits = searchHits.getHits();
for (org.elasticsearch.search.SearchHit hit : hitsHits) {
// System.out.println("hit = " + hit);
String json = hit.getSourceAsString();
System.out.println("高亮前json = " + json);
Product product = MAPPER.readValue(json, Product.class);
System.out.println("product = " + product);
// HighlightField highlightField = hit.getHighlightFields().get("title");
}
// 聚合结果集
Aggregations aggregations = response.getAggregations();
ParsedStringTerms brand = aggregations.get("brandAgg");
brand.getBuckets().forEach(bucket -> {
System.out.println(bucket.getKeyAsString());
System.out.println(bucket.getDocCount());
});
}
}