SpringBoot 使用 ElasticSearch 编程测试

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());
        });
    }
}

猜你喜欢

转载自blog.csdn.net/qq_45037155/article/details/130609981