1. 程式人生 > >樂優商城第十二天(Elasticsearch)

樂優商城第十二天(Elasticsearch)

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