樂優商城第十二天(Elasticsearch)
阿新 • • 發佈:2019-02-01
spring data Elasticsearch
1.匯入依賴
<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>
2.配置檔案,配置elasticsearch的地址
spring: data: elasticsearch: cluster-name: elasticsearch cluster-nodes: 192.168.56.101:9300
3.pojo
@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(index = false,type = FieldType.keyword) String images; // 圖片地址
4.開啟測試類進行測試
@SpringBootTest(classes = DemoApplication.class) @RunWith(SpringRunner.class) public class SearchTest {
建立索引,設定對映
@Test public void createIndex(){ esTemplate.createIndex(Item.class); esTemplate.putMapping(Item.class); }
刪除索引庫
@Test public void deleteindex(){ esTemplate.deleteIndex("cr7"); }
二.對索引庫中的資料增刪改查,spring data給我們提供了一個介面,使用時要繼承這個介面
public interface ItemRepository extends ElasticsearchRepository<Item,Long> {
這個Long是什麼意思?好像跟序列化有關係
1.儲存資料
@Test public void index(){ Item item = new Item(1L, "小米手機7", " 手機", "小米", 3499.00, "http://image.leyou.com/13123.jpg"); itemRepository.save(item); }
2.批量儲存資料
@Test public void indexList() { List<Item> list = new ArrayList<>(); list.add(new Item(2L, "堅果手機R1", " 手機", "錘子", 3699.00, "http://image.leyou.com/123.jpg")); list.add(new Item(3L, "華為META10", " 手機", "華為", 4499.00, "http://image.leyou.com/3.jpg")); // 接收物件集合,實現批量新增 itemRepository.saveAll(list); }
3.查詢全部,並按照價格排序
@Test public void query(){ // 查詢全部,並安裝價格降序排序 Iterable<Item> items = this.itemRepository.findAll(Sort.by("price").descending()); for (Item item : items) { System.out.println("item = " + item); } }
4.查詢一定價格區間
@Test public void queryByPriceBetween(){ List<Item> list = this.itemRepository.findByPriceBetween(2000.00, 3500.00); for (Item item : list) { System.out.println("item = " + item); } }
5.條件查詢
@Test public void search(){ // 構建查詢條件 NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder(); // 新增基本分詞查詢 queryBuilder.withQuery(QueryBuilders.matchQuery("title", "小米手機")); // 搜尋,獲取結果 Page<Item> items = this.itemRepository.search(queryBuilder.build()); // 總條數 long total = items.getTotalElements(); System.out.println("total = " + total); for (Item item : items) { System.out.println(item); } }
6.分頁查詢
/** * 分頁查詢 */ @Test public void searchByPage(){ // 構建查詢條件 NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder(); // 新增基本分詞查詢 queryBuilder.withQuery(QueryBuilders.termQuery("category", "手機")); // 分頁: int page = 0; int size = 2; queryBuilder.withPageable(PageRequest.of(page,size)); // 搜尋,獲取結果 Page<Item> items = this.itemRepository.search(queryBuilder.build()); // 總條數 long total = items.getTotalElements(); System.out.println("總條數 = " + total); // 總頁數 System.out.println("總頁數 = " + items.getTotalPages()); // 當前頁 System.out.println("當前頁:" + items.getNumber()); // 每頁大小 System.out.println("每頁大小:" + items.getSize()); for (Item item : items) { System.out.println(item); } }
7.根據分詞查詢,根據價格排序
@Test public void searchAndSort(){ // 構建查詢條件 NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder(); // 新增基本分詞查詢 queryBuilder.withQuery(QueryBuilders.termQuery("category", "手機")); // 排序 queryBuilder.withSort(SortBuilders.fieldSort("price").order(SortOrder.ASC)); // 搜尋,獲取結果 Page<Item> items = this.itemRepository.search(queryBuilder.build()); // 總條數 long total = items.getTotalElements(); System.out.println("總條數 = " + total); for (Item item : items) { System.out.println(item); } }
8.聚合為桶,根據品牌進行分桶
/** * 聚合為桶 */ @Test public void testAgg(){ NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder(); // 不查詢任何結果 queryBuilder.withSourceFilter(new FetchSourceFilter(new String[]{""}, null)); // 1、新增一個新的聚合,聚合型別為terms,聚合名稱為brands,聚合欄位為brand queryBuilder.addAggregation( AggregationBuilders.terms("brands").field("brand")); // 2、查詢,需要把結果強轉為AggregatedPage型別 AggregatedPage<Item> aggPage = (AggregatedPage<Item>) this.itemRepository.search(queryBuilder.build()); // 3、解析 // 3.1、從結果中取出名為brands的那個聚合, // 因為是利用String型別欄位來進行的term聚合,所以結果要強轉為StringTerm型別 StringTerms agg = (StringTerms) aggPage.getAggregation("brands"); // 3.2、獲取桶 List<StringTerms.Bucket> buckets = agg.getBuckets(); // 3.3、遍歷 for (StringTerms.Bucket bucket : buckets) { // 3.4、獲取桶中的key,即品牌名稱 System.out.println(bucket.getKeyAsString()); // 3.5、獲取桶中的文件數量 System.out.println(bucket.getDocCount()); } }
9.巢狀聚合,求平均值
/** * 巢狀聚合,求平均值 */ @Test public void testSubAgg(){ NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder(); // 不查詢任何結果 queryBuilder.withSourceFilter(new FetchSourceFilter(new String[]{""}, null)); // 1、新增一個新的聚合,聚合型別為terms,聚合名稱為brands,聚合欄位為brand queryBuilder.addAggregation( AggregationBuilders.terms("brands").field("brand") .subAggregation(AggregationBuilders.avg("priceAvg").field("price")) // 在品牌聚合桶內進行巢狀聚合,求平均值 ); // 2、查詢,需要把結果強轉為AggregatedPage型別 AggregatedPage<Item> aggPage = (AggregatedPage<Item>) this.itemRepository.search(queryBuilder.build()); // 3、解析 // 3.1、從結果中取出名為brands的那個聚合, // 因為是利用String型別欄位來進行的term聚合,所以結果要強轉為StringTerm型別 StringTerms agg = (StringTerms) aggPage.getAggregation("brands"); // 3.2、獲取桶 List<StringTerms.Bucket> buckets = agg.getBuckets(); // 3.3、遍歷 for (StringTerms.Bucket bucket : buckets) { // 3.4、獲取桶中的key,即品牌名稱 3.5、獲取桶中的文件數量 System.out.println(bucket.getKeyAsString() + ",共" + bucket.getDocCount() + "臺"); // 3.6.獲取子聚合結果: InternalAvg avg = (InternalAvg) bucket.getAggregations().asMap().get("priceAvg"); System.out.println("平均售價:" + avg.getValue()); } }