主頁 >  其他 > Java之Spring Data Elasticsearch一篇文章從入門到實戰

Java之Spring Data Elasticsearch一篇文章從入門到實戰

2021-08-22 07:01:57 其他

Elasticsearch提供的Java客戶端有一些不太方便的地方:

  • 很多地方需要拼接Json字串,在java中拼接字串有多恐怖你應該懂的
  • 需要自己把物件序列化為json存盤
  • 查詢到結果也需要自己反序列化為物件

因此,我們這里就不講解原生的Elasticsearch客戶端API了,

而是學習Spring提供的套件:Spring Data Elasticsearch,

一、簡介

Spring Data Elasticsearch是Spring Data專案下的一個子模塊,

查看 Spring Data的官網:http://projects.spring.io/spring-data/
在這里插入圖片描述
Spring Data 的使命是為資料訪問提供熟悉且一致的基于 Spring 的編程模型,同時仍保留底層資料存盤的特??殊特征,

它使使用資料訪問技術、關系和非關系資料庫、map-reduce 框架和基于云的資料服務變得容易,

這是一個傘形專案,其中包含許多特定于給定資料庫的子專案,

這些專案是通過與這些令人興奮的技術背后的許多公司和開發商合作開發的,

特征

  • 強大的存盤庫和自定義物件映射抽象

  • 從存盤庫方法名稱派生的動態查詢

  • 提供基本屬性的實作域基類

  • 支持透明審計(創建、最后更改)

  • 可以集成自定義存盤庫代碼

  • 通過 JavaConfig 和自定義 XML 命名空間輕松集成 Spring

  • 與 Spring MVC 控制器的高級集成

  • 跨店持久化實驗支持

1、Spring Data Elasticsearch

在這里插入圖片描述
在這里插入圖片描述
Spring Data for Elasticsearch 是 Spring Data 專案的一部分,該專案旨在為新資料存盤提供熟悉且一致的基于 Spring 的編程模型,同時保留特定于存盤的特性和功能,

Spring Data Elasticsearch 專案提供了與 Elasticsearch 搜索引擎的集成,Spring Data Elasticsearch 的關鍵功能領域是以 POJO 為中心的模型,用于與 Elastichsearch 檔案互動并輕松撰寫 Repository 樣式的資料訪問層,

(1)特征

  • Spring 配置支持使用基于 Java 的@Configuration類或用于 ES 客戶端實體的 XML 命名空間,

  • ElasticsearchTemplate幫助程式類,可提高執行常見 ES 操作的生產力,包括檔案和 POJO 之間的集成物件映射,

  • 功能豐富的物件映射與 Spring 的轉換服務集成

  • 基于注釋的映射元資料但可擴展以支持其他元資料格式

  • Repository介面的自動實作,包括對自定義查找器方法的支持,

  • 對存盤庫的 CDI 支持

二、Demo工程的搭建(創建索引)

我們新建一個demo,學習Elasticsearch

在這之前你需要在Linux上安裝Elasticsearch:
如果有則不需要安裝,入門沒有請看我的這篇文章:
https://blog.csdn.net/qq_44757034/article/details/119717907

1、創建一個新的工程

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

2、引入依賴

(1)pom.xml

在這里插入圖片描述

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.itzheng.demo</groupId>
    <artifactId>es-demo</artifactId>
    <version>1.0.0-SNAPSHOT</version>

    <name>elasticsearch</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.5.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <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>

(2)application.yml

在這里插入圖片描述
在這里插入圖片描述
其中192.168.56.10為你虛擬機或者服務器的ip地址

spring:
  data:
    elasticsearch:
      cluster-name: elasticsearch
      cluster-nodes: 192.168.56.101:9300

3、設定啟動類

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

package com.itzheng;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class EsApplication {
    public static void main(String[] args) {
        SpringApplication.run(EsApplication.class);
    }
}

4、創建物體類

在這里插入圖片描述
在這里插入圖片描述

package com.itzheng.es.pojo;

public class Item {

    private Long id;
    private String title;   //標題
    private String category;//分類
    private String brand;//品牌
    private Double price;//價格
    private String images;//圖片地址

}

添加依賴
在這里插入圖片描述

		<dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

完善物體類
在這里插入圖片描述

package com.itzheng.es.pojo;

import lombok.Data;

@Data
public class Item {
    private Long id;
    private String title;   //標題
    private String category;//分類
    private String brand;//品牌
    private Double price;//價格
    private String images;//圖片地址
}

5、創建測驗類

(1)創建索引庫

在這里插入圖片描述
在這里插入圖片描述

package com.itzheng.es.demo;

import com.itzheng.es.pojo.Item;
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.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.test.context.junit4.SpringRunner;
/*
Springboot的@RunWith(SpringRunner.class)
注解的意義在于Test測驗類要使用注入的類,比如@Autowired注入的類,
有了@RunWith(SpringRunner.class)這些類才能實體化到spring容器中,自動注入才能生效,
不然直接一個NullPointerExecption

 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class EsTest {
    @Autowired
    ElasticsearchTemplate template;

    @Test
    public void testCreate(){
        template.createIndex(Item.class);//創建索引
    }
}

完善物體類Item,設定在提交到Elasticsearch的時候的索引名稱,型別,以及分片
在這里插入圖片描述

package com.itzheng.es.pojo;

import lombok.Data;
import org.springframework.data.elasticsearch.annotations.Document;

@Data
@Document(indexName = "itzhengitem",type = "item",shards = 1)
public class Item {
    private Long id;
    private String title;   //標題
    private String category;//分類
    private String brand;//品牌
    private Double price;//價格
    private String images;//圖片地址
}

(2)指定映射關系

1)添加欄位映射(繼續完善Item物體類)設定型別和主鍵

映射

Spring Data通過注解來宣告欄位的映射屬性,有下面的三個注解:

  • @Document 作用在類,標記物體類為檔案物件,一般有四個屬性
    • indexName:對應索引庫名稱
    • type:對應在索引庫中的型別
    • shards:分片數量,默認5
    • replicas:副本數量,默認1
  • @Id 作用在成員變數,標記一個欄位作為id主鍵
  • @Field 作用在成員變數,標記為檔案的欄位,并指定欄位映射屬性:
    • type:欄位型別,取值是列舉:FieldType
    • index:是否索引,布爾型別,默認是true
    • store:是否存盤,布爾型別,默認是false
    • analyzer:分詞器名稱

示例:
在這里插入圖片描述

package com.itzheng.es.pojo;
import lombok.Data;
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;
@Data
@Document(indexName = "itzhengitem",type = "item",shards = 1)
@AllArgsConstructor
@NoArgsConstructor
public class Item {
    @Field(type = FieldType.Long)
    @Id
    private Long id;

    @Field(type = FieldType.Text , analyzer = "ik_smart")//設定型別是文本,并指定分詞方式為ik_smart
    private String title;   //標題

    @Field(type = FieldType.Keyword)  //Keyword設定當前也是文本型別,但是不設定分詞
    private String category;//分類

    @Field(type = FieldType.Keyword)
    private String brand;//品牌

    @Field(type = FieldType.Double)
    private Double price;//價格

    @Field(type = FieldType.Keyword,index = false)//index = false設定當前欄位不需要被索引,index = 默認是true
    private String images;//圖片地址
}

2)完善測驗類,使用映射規則

在這里插入圖片描述

package com.itzheng.es.demo;

import com.itzheng.es.pojo.Item;
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.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.test.context.junit4.SpringRunner;
/*
Springboot的@RunWith(SpringRunner.class)
注解的意義在于Test測驗類要使用注入的類,比如@Autowired注入的類,
有了@RunWith(SpringRunner.class)這些類才能實體化到spring容器中,自動注入才能生效,
不然直接一個NullPointerExecption
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class EsTest {
    @Autowired
    ElasticsearchTemplate template;

    @Test
    public void testCreate(){
        //創建索引庫
        template.createIndex(Item.class);//創建索引
        //指定映射關系
        template.putMapping(Item.class);
    }
}

6、運行測驗類

(1)運行測驗

在這里插入圖片描述
在這里插入圖片描述
運行成功
在這里插入圖片描述

(2)通過Kabina查看

在這里插入圖片描述

GET itzhengitem

回傳結果

{
  "itzhengitem" : {
    "aliases" : { },
    "mappings" : {
      "properties" : {
        "brand" : {
          "type" : "keyword"
        },
        "category" : {
          "type" : "keyword"
        },
        "id" : {
          "type" : "keyword"
        },
        "images" : {
          "type" : "keyword",
          "index" : false
        },
        "price" : {
          "type" : "double"
        },
        "title" : {
          "type" : "text",
          "analyzer" : "ik_smart"
        }
      }
    },
    "settings" : {
      "index" : {
        "routing" : {
          "allocation" : {
            "include" : {
              "_tier_preference" : "data_content"
            }
          }
        },
        "refresh_interval" : "1s",
        "number_of_shards" : "1",
        "provided_name" : "itzhengitem",
        "creation_date" : "1629355397115",
        "store" : {
          "type" : "fs"
        },
        "number_of_replicas" : "1",
        "uuid" : "2cUsvBtgQ4uOARwTuQoHAA",
        "version" : {
          "created" : "7140099"
        }
      }
    }
  }
}

在這里插入圖片描述

只查看映射

GET itzhengitem/_mapping
{
  "itzhengitem" : {
    "mappings" : {
      "properties" : {
        "brand" : {
          "type" : "keyword"
        },
        "category" : {
          "type" : "keyword"
        },
        "id" : {
          "type" : "keyword"
        },
        "images" : {
          "type" : "keyword",
          "index" : false
        },
        "price" : {
          "type" : "double"
        },
        "title" : {
          "type" : "text",
          "analyzer" : "ik_smart"
        }
      }
    }
  }
}

在這里插入圖片描述

三、洗掉索引

1、撰寫測驗方法

在這里插入圖片描述

package com.itzheng.es.demo;

import com.itzheng.es.pojo.Item;
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.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.test.context.junit4.SpringRunner;
/*
Springboot的@RunWith(SpringRunner.class)
注解的意義在于Test測驗類要使用注入的類,比如@Autowired注入的類,
有了@RunWith(SpringRunner.class)這些類才能實體化到spring容器中,自動注入才能生效,
不然直接一個NullPointerExecption
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class EsTest {
    @Autowired
    ElasticsearchTemplate template;

    @Test
    public void testCreate(){
        //創建索引庫
        template.createIndex(Item.class);//創建索引
        //指定映射關系
        template.putMapping(Item.class);

    }

    @Test
    public void testDelete(){
        template.deleteIndex("itzhengitem");
    }
}

在這里插入圖片描述
運行成功
在這里插入圖片描述

2、通過Kabina查看

GET itzhengitem

回傳結果

{
  "error" : {
    "root_cause" : [
      {
        "type" : "index_not_found_exception",
        "reason" : "no such index [itzhengitem]",
        "resource.type" : "index_or_alias",
        "resource.id" : "itzhengitem",
        "index_uuid" : "_na_",
        "index" : "itzhengitem"
      }
    ],
    "type" : "index_not_found_exception",
    "reason" : "no such index [itzhengitem]",
    "resource.type" : "index_or_alias",
    "resource.id" : "itzhengitem",
    "index_uuid" : "_na_",
    "index" : "itzhengitem"
  },
  "status" : 404
}

為了方便我們需要再次創建剛剛的索引
在這里插入圖片描述

四、Repository檔案操作

Spring Data 的強大之處,就在于你不用寫任何DAO處理,自動根據方法名或類的資訊進行CRUD操作,

只要你定義一個介面,然后繼承Repository提供的一些子介面,就能具備各種基本的CRUD功能,

我們只需要定義介面,然后繼承它就OK了,

定義一個介面
在這里插入圖片描述

package com.itzheng.es.repository;

import com.itzheng.es.pojo.Item;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;

public interface ItemRepository extends ElasticsearchRepository<Item,Long> {
//上述泛型的第一個引數的物體型別別,第二個是主鍵ID型別

}

1、新增檔案

(1)首先注入

在這里插入圖片描述


    @Autowired
    private ItemRepository repository;

(2)撰寫測驗方法

在這里插入圖片描述


    @Test
    public void insertIndex(){
        Item item = new Item(1L, "小米手機7", " 手機", "小米", 3499.00, "http://image.leyou.com/13123.jpg");
        repository.save(item);
    }

(3)運行測驗方法

在這里插入圖片描述
在這里插入圖片描述

(4)通過Kabina查看

GET itzhengitem/_search
{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "itzhengitem",
        "_type" : "item",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "id" : 1,
          "title" : "小米手機7",
          "category" : " 手機",
          "brand" : "小米",
          "price" : 3499.0,
          "images" : "http://image.leyou.com/13123.jpg"
        }
      }
    ]
  }
}

在這里插入圖片描述

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"));
        repository.saveAll(list);
    }


運行測驗
在這里插入圖片描述
運行成功
在這里插入圖片描述
通過Kabina查看

GET itzhengitem/_search
{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 3,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "itzhengitem",
        "_type" : "item",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "id" : 1,
          "title" : "小米手機7",
          "category" : " 手機",
          "brand" : "小米",
          "price" : 3499.0,
          "images" : "http://image.leyou.com/13123.jpg"
        }
      },
      {
        "_index" : "itzhengitem",
        "_type" : "item",
        "_id" : "2",
        "_score" : 1.0,
        "_source" : {
          "id" : 2,
          "title" : "堅果手機R1",
          "category" : " 手機",
          "brand" : "錘子",
          "price" : 3699.0,
          "images" : "http://image.leyou.com/123.jpg"
        }
      },
      {
        "_index" : "itzhengitem",
        "_type" : "item",
        "_id" : "3",
        "_score" : 1.0,
        "_source" : {
          "id" : 3,
          "title" : "華為META10",
          "category" : " 手機",
          "brand" : "華為",
          "price" : 4499.0,
          "images" : "http://image.leyou.com/3.jpg"
        }
      }
    ]
  }
}

多新增幾條資料


    @Test
    public void indexList(){

        List<Item> list = new ArrayList<>();
        list.add(new Item(4L, "小米手機7", "手機", "小米", 3299.00, "http://image.leyou.com/13123.jpg"));
        list.add(new Item(5L, "堅果手機R1", "手機", "錘子", 3699.00, "http://image.leyou.com/13123.jpg"));
        list.add(new Item(6L, "華為META10", "手機", "華為", 4499.00, "http://image.leyou.com/13123.jpg"));
        list.add(new Item(7L, "小米Mix2S", "手機", "小米", 4299.00, "http://image.leyou.com/13123.jpg"));
        list.add(new Item(8L, "榮耀V10", "手機", "華為", 2799.00, "http://image.leyou.com/13123.jpg"));
        repository.saveAll(list);
    }

3、修改檔案

修改和新增是同一個介面,區分的依據就是id

這一點跟我們在頁面發起PUT請求是類似的,

修改id為1 的資料
在這里插入圖片描述


    @Test
    public void updateIndex(){
        Item item = new Item(1L, "大米手機7", " 手機", "小米", 3499.00, "http://image.leyou.com/13123.jpg");
        repository.save(item);
    }

在這里插入圖片描述
通過Kabina查看

GET itzhengitem/_search

在這里插入圖片描述

4、基本查詢

ElasticsearchRepository提供了一些基本的查詢方法:

(1)通過id查詢

在這里插入圖片描述


    @Test
    public void testQuery(){
        Optional<Item> optional = this.repository.findById(1L);
        System.out.println(optional.get());
    }

在這里插入圖片描述
在這里插入圖片描述

(2)查詢所有

在這里插入圖片描述

  @Test
    public void testFind(){
        Iterable<Item> items = repository.findAll();

        for (Item item : items) {
            System.out.println(item);
        }
    }

在這里插入圖片描述
運行結果
在這里插入圖片描述

(3) 自定義方法

Spring Data 的另一個強大功能,是根據方法名稱自動實作功能,

比如:你的方法名叫做:findByTitle,那么它就知道你是根據title查詢,然后自動幫你完成,無需寫實作類,

當然,方法名稱要符合一定的約定:

KeywordSampleElasticsearch Query String
AndfindByNameAndPrice{"bool" : {"must" : [ {"field" : {"name" : "?"}}, {"field" : {"price" : "?"}} ]}}
OrfindByNameOrPrice{"bool" : {"should" : [ {"field" : {"name" : "?"}}, {"field" : {"price" : "?"}} ]}}
IsfindByName{"bool" : {"must" : {"field" : {"name" : "?"}}}}
NotfindByNameNot{"bool" : {"must_not" : {"field" : {"name" : "?"}}}}
BetweenfindByPriceBetween{"bool" : {"must" : {"range" : {"price" : {"from" : ?,"to" : ?,"include_lower" : true,"include_upper" : true}}}}}
LessThanEqualfindByPriceLessThan{"bool" : {"must" : {"range" : {"price" : {"from" : null,"to" : ?,"include_lower" : true,"include_upper" : true}}}}}
GreaterThanEqualfindByPriceGreaterThan{"bool" : {"must" : {"range" : {"price" : {"from" : ?,"to" : null,"include_lower" : true,"include_upper" : true}}}}}
BeforefindByPriceBefore{"bool" : {"must" : {"range" : {"price" : {"from" : null,"to" : ?,"include_lower" : true,"include_upper" : true}}}}}
AfterfindByPriceAfter{"bool" : {"must" : {"range" : {"price" : {"from" : ?,"to" : null,"include_lower" : true,"include_upper" : true}}}}}
LikefindByNameLike{"bool" : {"must" : {"field" : {"name" : {"query" : "?*","analyze_wildcard" : true}}}}}
StartingWithfindByNameStartingWith{"bool" : {"must" : {"field" : {"name" : {"query" : "?*","analyze_wildcard" : true}}}}}
EndingWithfindByNameEndingWith{"bool" : {"must" : {"field" : {"name" : {"query" : "*?","analyze_wildcard" : true}}}}}
Contains/ContainingfindByNameContaining{"bool" : {"must" : {"field" : {"name" : {"query" : "**?**","analyze_wildcard" : true}}}}}
InfindByNameIn(Collection<String>names){"bool" : {"must" : {"bool" : {"should" : [ {"field" : {"name" : "?"}}, {"field" : {"name" : "?"}} ]}}}}
NotInfindByNameNotIn(Collection<String>names){"bool" : {"must_not" : {"bool" : {"should" : {"field" : {"name" : "?"}}}}}}
NearfindByStoreNearNot Supported Yet !
TruefindByAvailableTrue{"bool" : {"must" : {"field" : {"available" : true}}}}
FalsefindByAvailableFalse{"bool" : {"must" : {"field" : {"available" : false}}}}
OrderByfindByAvailableTrueOrderByNameDesc{"sort" : [{ "name" : {"order" : "desc"} }],"bool" : {"must" : {"field" : {"available" : true}}}}

例如,我們來按照價格區間查詢,定義這樣的一個方法:

1)在介面當中定義

在這里插入圖片描述

package com.itzheng.es.repository;

import com.itzheng.es.pojo.Item;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;

import java.util.List;

public interface ItemRepository extends ElasticsearchRepository<Item,Long> {
//上述泛型的第一個引數的物體型別別,第二個是主鍵ID型別

    List<Item> findByPriceBetween(double price1, double price2);

}

2)在EsTest撰寫queryByPriceBetween方法(通過價格的范圍查詢)

不需要寫實作類,然后我們直接去運行:
在這里插入圖片描述


    @Test
    public void queryByPriceBetween(){

        List<Item> items = repository.findByPriceBetween(2000, 4000);
        for (Item item : items) {
            System.out.println(item);
        }

    }

在這里插入圖片描述
在這里插入圖片描述

5、高級查詢

(1)基本查詢

先看看基本玩法
在這里插入圖片描述


    @Test
    public void testQueryCustom(){
        //詞條查詢
        MatchQueryBuilder queryBuilder = QueryBuilders.matchQuery("title", "小米");
        Iterable<Item> items = repository.search(queryBuilder);
        items.forEach(System.out::println);

    }


QueryBuilders提供了大量的靜態方法,用于生成各種不同型別的查詢物件,例如:詞條、模糊、通配符等QueryBuilder物件,

結果:
在這里插入圖片描述

(2)自定義查詢

先來看最基本的match query:
在這里插入圖片描述


    @Test
    public void testNativeQuery(){
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        //結果過濾
        //添加查詢條件
        queryBuilder.withQuery(QueryBuilders.matchQuery("title","小米"));
        NativeSearchQuery searchQuery = queryBuilder.build();
        //執行搜索,獲取結果
        Page<Item> result = repository.search(searchQuery);
        //列印總條數
        System.out.println(result.getTotalElements());
        //列印總頁數
        System.out.println(result.getTotalPages());
        result.forEach(System.out::println);
    }

NativeSearchQueryBuilder:Spring提供的一個查詢條件構建器,幫助構建json格式的請求體

Page<item>:默認是分頁查詢,因此回傳的是一個分頁的結果物件,包含屬性:

  • totalElements:總條數
  • totalPages:總頁數
  • Iterator:迭代器,本身實作了Iterator介面,因此可直接迭代得到當前頁的資料

回傳結果
在這里插入圖片描述

(3)分頁查詢和排序

利用NativeSearchQueryBuilder可以方便的實作分頁:

需要再添加一些資料方便測驗


    @Test
    public void indexList(){

        List<Item> list = new ArrayList<>();
        list.add(new Item(9L, "小米手機7", "手機", "小米", 3299.00, "http://image.leyou.com/13123.jpg"));
        list.add(new Item(10L, "堅果手機R1", "手機", "錘子", 3699.00, "http://image.leyou.com/13123.jpg"));
        list.add(new Item(11L, "華為META10", "手機", "華為", 4499.00, "http://image.leyou.com/13123.jpg"));
        list.add(new Item(12L, "小米Mix2S", "手機", "小米", 4299.00, "http://image.leyou.com/13123.jpg"));
        list.add(new Item(13L, "榮耀V10", "手機", "華為", 2799.00, "http://image.leyou.com/13123.jpg"));
        repository.saveAll(list);
    }

再次測驗
在這里插入圖片描述

  @Test
    public void testNativeQuery(){
        // 構建查詢條件
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        // 添加基本的分詞查詢
        queryBuilder.withQuery(QueryBuilders.termQuery("title", "手機"));
        // 初始化分頁引數
        int page = 0;
        int size = 3;
        // 設定分頁引數
        queryBuilder.withPageable(PageRequest.of(page, size));
        // 執行搜索,獲取結果
        Page<Item> items = this.repository.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 testNativeQuery(){
        // 構建查詢條件
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        // 添加基本的分詞查詢
        queryBuilder.withQuery(QueryBuilders.termQuery("title", "手機"));
        // 初始化分頁引數
        int page = 1;
        int size = 3;
        // 設定分頁引數
        queryBuilder.withPageable(PageRequest.of(page, size));
        // 執行搜索,獲取結果
        Page<Item> items = this.repository.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);
    }

在這里插入圖片描述
1是當前頁

6、聚合

(1)聚合為桶

桶就是分組,比如這里我們按照品牌brand進行分組:

在這里插入圖片描述

    @Test
    public void testAgg(){

        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        String aggName = "popularBrand";
        //聚合
        // AggregationBuilders.terms("popularBrand").field("brand")
        // terms聚合型別(查詢關鍵字)  popularBrand聚合名稱  brand聚合欄位
        queryBuilder.addAggregation(AggregationBuilders.terms(aggName).field("brand"));
        //查詢并回傳帶聚合結果
        AggregatedPage<Item> result = template.queryForPage(queryBuilder.build(), Item.class);
        //決議聚合
        Aggregations aggs = result.getAggregations();//得到了當前查詢的JSON集合

        //獲取指定名稱的聚合
        StringTerms terms = aggs.get(aggName);
        //獲取桶
        List<StringTerms.Bucket> buckets = terms.getBuckets();
        for (StringTerms.Bucket bucket : buckets) {
            System.out.println("bucket.getKeyAsString() = "+bucket.getKeyAsString());
            System.out.println("bucket.getDocCount() = "+bucket.getDocCount());
        }
    }

結果
在這里插入圖片描述

在這里插入圖片描述

(2)嵌套聚合,求平均值

在這里插入圖片描述

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



    }

在這里插入圖片描述

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/295365.html

標籤:其他

上一篇:Hive中的資料型別

下一篇:分布式框架之(三)服務注冊中心Zookeeper

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more