elasticsearch+spring boot 的初级代码

mac2022-06-30  137

依赖

<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.8.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.example</groupId> <artifactId>es</artifactId> <version>0.0.1-SNAPSHOT</version> <name>es</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <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> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>

实体类

package com.example.pojo; 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; @Document(indexName = "item",type = "docs",shards = 1,replicas = 0) public class Item { @Id Long id; @Field(type = FieldType.Text,analyzer = "ik_max_word") String title; //标题 @Field(type = FieldType.Keyword) String category;// 分类 @Field(type = FieldType.Keyword) String brand; // 品牌 @Field(type = FieldType.Double) Double price; // 价格 @Field(type = FieldType.Keyword,index = false) String images; // 图片地址 public Item() { } public Item(Long id, String title, String category, String brand, Double price, String images) { this.id = id; this.title = title; this.category = category; this.brand = brand; this.price = price; this.images = images; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getCategory() { return category; } public void setCategory(String category) { this.category = category; } public String getBrand() { return brand; } public void setBrand(String brand) { this.brand = brand; } public Double getPrice() { return price; } public void setPrice(Double price) { this.price = price; } public String getImages() { return images; } public void setImages(String images) { this.images = images; } @Override public String toString() { return "Item{" + "id=" + id + ", title='" + title + '\'' + ", category='" + category + '\'' + ", brand='" + brand + '\'' + ", price=" + price + ", images='" + images + '\'' + '}'; } }

Repository接口

package com.example.repository; import com.example.pojo.Item; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; import java.util.List; public interface ItemRepository extends ElasticsearchRepository<Item,Long> { List<Item> findByTitle(String title); }

测试类(注意:一般情况下,我们使用Repository子类对象去实现增删改(也可以查),elasticsearchTemplate对象去实现查询.区别:可以去具体看聚合的两种实现方式,elasticsearchTemplate方式的好处在于可以直接获取聚合分页结果,无需转换)

package com.example.pojo; import com.example.EsApplication; import com.example.repository.ItemRepository; import org.elasticsearch.index.query.MatchQueryBuilder; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.search.aggregations.Aggregation; import org.elasticsearch.search.aggregations.AggregationBuilders; import org.elasticsearch.search.aggregations.Aggregations; import org.elasticsearch.search.aggregations.bucket.terms.StringTerms; import org.elasticsearch.search.aggregations.metrics.avg.InternalAvg; import org.elasticsearch.search.sort.SortBuilders; import org.elasticsearch.search.sort.SortOrder; 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.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; import org.springframework.data.elasticsearch.core.query.FetchSourceFilter; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.test.context.junit4.SpringRunner; import java.util.ArrayList; import java.util.List; import java.util.Optional; @RunWith(SpringRunner.class) @SpringBootTest(classes = EsApplication.class) public class ItemTest { @Autowired private ElasticsearchTemplate elasticsearchTemplate; @Autowired private ItemRepository itemRepository; /** * 新增索引 */ @Test public void create() { //创建索引 elasticsearchTemplate.createIndex(Item.class); //添加映射 elasticsearchTemplate.putMapping(Item.class); } /** * 新增文档 */ @Test public void index() { Item item = new Item(1L, "小米手机7", " 手机", "小米", 3499.00, "http://image.leyou.com/13123.jpg"); itemRepository.save(item); } /** * 批量新增文档 */ @Test public void indexList() { List<Item> items = new ArrayList<>(); items.add(new Item(2L, "坚果手机R1", " 手机", "锤子", 3699.00, "http://image.leyou.com/123.jpg")); items.add(new Item(1L, "小米手机7", "手机", "小米", 3299.00, "http://image.leyou.com/13123.jpg")); items.add(new Item(3L, "华为META10", "手机", "华为", 4499.00, "http://image.leyou.com/13123.jpg")); items.add(new Item(4L, "小米Mix2S", "手机", "小米", 4299.00, "http://image.leyou.com/13123.jpg")); items.add(new Item(5L, "荣耀V10", "手机", "华为", 2799.00, "http://image.leyou.com/13123.jpg")); itemRepository.saveAll(items); } /** * 按id查询 */ @Test public void query() { Optional<Item> byId = itemRepository.findById(1L); System.out.println("byId = " + byId); System.out.println("byId = " + byId.get()); } /** * 查询所有 */ @Test public void queryAll() { Iterable<Item> items = itemRepository.findAll(); items.forEach(item -> System.out.println(item)); } /** * 自定义方法(根据规定的方法名,不需要写实现) */ @Test public void findByTitle() { List<Item> items = itemRepository.findByTitle("小米"); items.forEach(System.out::println); } /** * 高级查询之基本查询 */ @Test public void testQuery() { MatchQueryBuilder queryBuilder = QueryBuilders.matchQuery("title", "小米"); Iterable<Item> items = itemRepository.search(queryBuilder); // items.forEach(System.out::println); } /** * 自定义查询(从这开始的查询可以用elasticsearchTemplate对象替代) */ @Test public void nativeSearch() { NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder(); queryBuilder.withQuery(QueryBuilders.matchQuery("title", "小米")); Page<Item> items = itemRepository.search(queryBuilder.build()); // AggregatedPage<Item> aggregatedPage = elasticsearchTemplate.queryForPage(queryBuilder.build(), Item.class); System.out.println(items.getTotalElements()); System.out.println(items.getTotalPages()); items.forEach(System.out::println); } /** * 分页查询 */ @Test public void pageQuery() { NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder(); queryBuilder.withQuery(QueryBuilders.termQuery("category", "手机")); //定义分页条件 //当前页,从零开始呢 Integer page = 0; //每页大小 Integer size = 2; //queryBuilder.withQuery(PageRequest.of(page, size)); queryBuilder.withPageable(PageRequest.of(page, size)); Page<Item> items = itemRepository.search(queryBuilder.build()); //查询到总记录数 System.out.println(items.getTotalElements()); //查询到的总页数 System.out.println(items.getTotalPages()); //每页大小 System.out.println(items.getSize()); //当前页 System.out.println(items.getNumber()); items.forEach(System.out::println); } /** * 排序查询 */ @Test public void sort() { NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder(); queryBuilder.withQuery(QueryBuilders.termQuery("category", "手机")); queryBuilder.withSort(SortBuilders.fieldSort("price").order(SortOrder.DESC)); Page<Item> items = itemRepository.search(queryBuilder.build()); //总条数 System.out.println(items.getTotalElements()); items.forEach(System.out::println); } /** * 聚合查询---Repository */ @Test public void aggregationByRepository() { NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder(); //不查询任何结果 queryBuilder.withSourceFilter(new FetchSourceFilter(new String[]{""}, null)); // 1、添加一个新的聚合,聚合类型为terms,聚合名称为brands,聚合字段为brand queryBuilder.addAggregation(AggregationBuilders.terms("brands").field("brand")); // 2、查询,需要把结果强转为AggregatedPage类型 //Page<Item> items = itemRepository.search(queryBuilder.build()); AggregatedPage<Item> aggregatedPage = (AggregatedPage<Item>) itemRepository.search(queryBuilder.build()); // 3、解析 // 3.1、从结果中取出名为brands的那个聚合, // 因为是利用String类型字段来进行的term聚合,所以结果要强转为StringTerm类型 //Aggregation brands = aggregatedPage.getAggregation("brands"); StringTerms brands = (StringTerms) aggregatedPage.getAggregation("brands"); List<StringTerms.Bucket> buckets = brands.getBuckets(); buckets.forEach(bucket -> { //获取桶中的key,即品牌名称 System.out.println(bucket.getKeyAsString()); //获取桶中的文档数量 System.out.println(bucket.getDocCount()); }); } /** * 聚合查询---elasticsearchTemplate */ @Test public void aggregationByElasticsearchTemplate() { NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder(); //不查询任何结果 queryBuilder.withSourceFilter(new FetchSourceFilter(new String[]{""}, null)); // 1、添加一个新的聚合,聚合类型为terms,聚合名称为brands,聚合字段为brand queryBuilder.addAggregation(AggregationBuilders.terms("brands").field("brand")); // 2、查询 AggregatedPage<Item> aggregatedPage = elasticsearchTemplate.queryForPage(queryBuilder.build(),Item.class); // 3、解析 // 3.1、从结果中取出名为brands的那个聚合, // 因为是利用String类型字段来进行的term聚合,所以结果要强转为StringTerm类型 //StringTerms brands = (StringTerms) aggregatedPage.getAggregation("brands"); Aggregations aggregations = aggregatedPage.getAggregations(); StringTerms brands = aggregations.get("brands"); List<StringTerms.Bucket> buckets = brands.getBuckets(); buckets.forEach(bucket -> { //获取桶中的key,即品牌名称 System.out.println(bucket.getKeyAsString()); //获取桶中的文档数量 System.out.println(bucket.getDocCount()); }); } /** * 桶内嵌套桶 */ @Test public void subAggregation() { NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder(); //不要查询结果 queryBuilder.withSourceFilter(new FetchSourceFilter(new String[]{""}, null)); //添加一个新的聚合,聚合类型为terms,聚合名称为brands,聚合字段为brand //在品牌聚合桶内进行嵌套聚合,求平均值 queryBuilder.addAggregation(AggregationBuilders.terms("brands").field("brand"). subAggregation(AggregationBuilders.avg("priceAvg").field("price"))); AggregatedPage<Item> aggregatedPage = (AggregatedPage<Item>) itemRepository.search(queryBuilder.build()); StringTerms brands = (StringTerms) aggregatedPage.getAggregation("brands"); List<StringTerms.Bucket> buckets = brands.getBuckets(); buckets.forEach(bucket -> { //获取桶中的key,即品牌名称 System.out.println(bucket.getKeyAsString()); //获取桶中的文档数量 System.out.println(bucket.getDocCount()); //获取子聚合结果 InternalAvg priceAvg = (InternalAvg) bucket.getAggregations().asMap().get("priceAvg"); System.out.println(priceAvg.getValue()); }); } }
最新回复(0)