ElasticSearch,docker 安装ElasticSearch,Springboot 使用 ElasticSearch JavaAPI
什么是 ElasticSearch ?
數據庫查詢存在的問題:
性能低:使用模糊查詢,左邊有通配符,不會走索引,會全表掃描,性能低
關鍵字模糊查詢比較麻煩
ElasticSearch概念
? ElasticSearch是一個基于Lucene的搜索服務器
? 是一個分布式、高擴展、高實時的搜索與數據分析引擎
? 基于RESTful web接口
? Elasticsearch是用Java語言開發的,并作為Apache許可條款下的開放源碼發布,是一種流行的企業級搜索引擎
? 官網:https://www.elastic.co/
應用場景
? 搜索:海量數據的查詢
? 日志數據分析
? 實時數據分析
ElasticSearch與MySql分工
? MySQL有事務性,而ElasticSearch沒有事務性,所以你刪了的數據是無法恢復的。
? ElasticSearch沒有物理外鍵這個特性,,如果你的數據強一致性要求比較高,還是建議慎用
ElasticSearch和MySql分工不同,MySQL負責存儲數據,ElasticSearch負責搜索數據。
ElasticSearch 核心概念
? 索引(index)
ElasticSearch存儲數據的地方,可以理解成關系型數據庫中的數據庫概念。
? 映射(mapping)
mapping定義了每個字段的類型、字段所使用的分詞器等。相當于關系型數據庫中的表結構。
? 文檔(document)
Elasticsearch中的最小數據單元,常以json格式顯示。一個document相當于關系型數據庫中的一行數據。
? 倒排索引
一個倒排索引由文檔中所有不重復詞的列表構成,對于其中每個詞,對應一個包含它的文檔id列表。
? 類型(type)
一種type就像一類表。如用戶表、角色表等。在Elasticsearch7.X默認type為_doc
- ES 5.x中一個index可以有多種type。
- ES 6.x中一個index只能有一種type。
- ES 7.x以后,將逐步移除type這個概念,現在的操作已經不再使用,默認_doc
RESTful風格
? REST(Representational State Transfer),表述性狀態轉移,是一組架構約束條件和原則。滿足這些約束條件和
原則的應用程序或設計就是RESTful。就是一種定義接口的規范。
? 基于HTTP。
? 可以使用XML格式定義或JSON格式定義。
? 每一個URI代表1種資源。
? 客戶端使用GET、POST、PUT、DELETE 4個表示操作方式的動詞對服務端資源進行操作:
? GET:用來獲取資源
? POST:用來新建資源(也可以用于更新資源)
? PUT:用來更新資源
? DELETE:用來刪除資源
docker安裝ElasticSearch
# 拉取elasticsearch鏡像 docker pull elasticsearch:7.6.2 # 啟動容器 docker run -d -e ES_JAVA_POTS="-Xms512m -Xmx512m" --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2# 然后docker ps -a 查看啟動成功沒有,logs查看日志 等待一會 去瀏覽器訪問一下9200 啟動時間有點久,多等一會兒# 拉取kibana鏡像 docker pull kibana:7.6.2 # 啟動容器 docker run -d -p 5601:5601 --name=kibana --link elasticsearch -e "ELASTICSEARCH_URL=http://es安裝的ip:9200" kibana:7.6.2# 然后查看容器,等待一會兒刷新一下 5601去看看 多等一會 ps -a 看容器啟動成功沒有 多刷新#Kibana在6.7以后的版本,支持了多種語言。并且自帶在安裝包里。修改方式如下:# 修改中文 docker exec -it kibana /bin/bash cd config vi kibana.yml #在kibana.yml配置文件中新增一行:i18n.locale: "zh-CN" # 安裝ik docker exec -it elasticsearch /bin/bash# 之后從github上抓取ik分詞器的壓縮包: 也可以復制在瀏覽器中下載后 docker cp 到容器指定的目錄中https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.6.2/elasticsearch-analysis-ik-7.6.2.zip# 之后再plugins下建立ik文件夾將壓縮包解壓進入此文件夾:cd plugins/ mv ../elasticsearch-analysis-ik-7.6.2.zip ./ik/ unzip elasticsearch-analysis-ik-7.6.2.zip之后編輯plugin-descriptor.properties文件vi plugin-descriptor.properties# 在文件最后一行添加這行(打開發現有這一行,就不用添加) elasticsearch.version=7.6.2操作 ElasticSearch
操作索引
在Kibana中操作
# 添加索引 PUT xiaofu_index# 查詢多個索引 GET goods_index,xiaofu_index# 查詢所有索引 GET _all# 刪除索引 DELETE xiaofu操作映射
操作文檔
分詞器
? 分詞器(Analyzer):將一段文本,按照一定邏輯,分析成多個詞語的一種工具
如:華為手機 — > 華為、手、手機
? ElasticSearch 內置分詞器
? Standard Analyzer - 默認分詞器,按詞切分,小寫處理
? Simple Analyzer - 按照非字母切分(符號被過濾), 小寫處理
? Stop Analyzer - 小寫處理,停用詞過濾(the,a,is)
? Whitespace Analyzer - 按照空格切分,不轉小寫
? Keyword Analyzer - 不分詞,直接將輸入當作輸出
? Patter Analyzer - 正則表達式,默認\W+(非字符分割)
? Language - 提供了30多種常見語言的分詞器
? ElasticSearch 內置分詞器對中文很不友好,處理方式為:一個字一個詞
IK分詞器
? IKAnalyzer是一個開源的,基于java語言開發的輕量級的中文分詞工具包
? 是一個基于Maven構建的項目
? 具有60萬字/秒的高速處理能力
? 支持用戶詞典擴展定義
? 下載地址:https://github.com/medcl/elasticsearch-analysis-ik/archive/v7.6.2.zip
查詢文檔
? 詞條查詢:term
? 詞條查詢不會分析查詢條件,只有當詞條和查詢字符串完全匹配時才匹配搜索
? 全文查詢:match
? 全文查詢會分析查詢條件,先將查詢條件進行分詞,然后查詢,求并集
kibana 測試
# 添加映射 PUT user/_mapping {"properties":{"name":{"type":"text"},"age":{"type":"integer"}} }# 創建索引 PUT person# 添加映射 PUT person/_mapping {"properties":{"name":{"type":"keyword"}} }# 查詢映射 GET user/_mapping GET person/_mapping# 添加文檔#1.添加文檔,指定ID PUT user/_doc/1 {"name":"小付","age":18,"address":"重慶" }#2.添加文檔,不指定ID ,會默認給ID POST user/_doc {"name":"小花","age":18,"address":"四川" }# 查詢文檔根據id GET user/_doc/1# 查詢文檔使用默認生成的ID GET user/_doc/Ch9dWHQB3VMI6Uwz9joI# 修改文檔,id有就修改,沒有就添加 PUT user/_doc/1 {"name":"小付","age":18,"address":"重慶" }# 查詢所有文檔 GET user/_search# 刪除文檔 根據ID DELETE user/_doc/2# 安裝ik后測試中文分詞器 細粒度 GET _analyze {"analyzer": "ik_max_word","text": "我愛北京天安門" }# 粗粒度 GET _analyze {"analyzer": "ik_smart","text": "我愛北京天安門" }# 使用腳本 # 查詢文檔# 查詢所有 GET user/_search# 添加一條 PUT user/_doc/3 {"name":"小甜","age":18,"address":"華為5G手機" }# term 詞條查詢,查詢的條件字符串和詞條完全匹配 # es默認使用的分詞器是standard 分詞效果是一個字一個詞 # 所以我們下面這個查詢不到 GET user/_search {"query": {"term": {"address": {"value": "重慶"}}} }# 從新創建索引添加映射 指定ik分詞器 # analyzer 指定分詞器 # search_analyzer 指定搜索時的分詞器 PUT phone {"mappings": {"properties": {"name":{"type": "keyword"},"address":{"type": "text","analyzer": "ik_max_word"}}} }Springboot 使用 ElasticSearch JavaAPI(注釋為詳細解釋)
springboot 導入 ElasticSearch JavaAPI 包
ElasticSearch 整合其余的項目
<!--引入es的坐標--><dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId><version>7.6.2</version></dependency><dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-client</artifactId><version>7.6.2</version></dependency><dependency><groupId>org.elasticsearch</groupId><artifactId>elasticsearch</artifactId><version>7.6.2</version></dependency>ESConfig
將 RestHighLevelClient 連接對象注入到IOC中
package com.fs.config;import org.apache.http.HttpHost; import org.elasticsearch.client.RestClient; import org.elasticsearch.client.RestHighLevelClient; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;//elasticsearch配置 @Configuration public class ESConfig {@Value("${es.host}")private String host;@Value("${es.port}")private Integer port;//創建RestHighLevelClient交給springIOC容器@Beanpublic RestHighLevelClient getRestHighLevelClient(){RestHighLevelClient restHighLevelClient = new RestHighLevelClient(RestClient.builder(new HttpHost(host,port,"http")));return restHighLevelClient;} }StudyEsApiApplicationTests 測試類
/* es 7.6.2 高級客戶端測試*/ @SpringBootTest class StudyEsApiApplicationTests {//注入es客戶端@Autowired@Qualifier("getRestHighLevelClient")private RestHighLevelClient restHighLevelClient;//注入goods@Autowiredprivate GoodsMapper goodsMapper; //.... 測試方法在后面 }測試操作索引
? 添加索引
? 查詢索引
? 刪除索引
? 判斷索引是否存
測試操作文檔
? 添加文檔
? 修改文檔
? 根據id查詢文檔
? 刪除文檔
對應kibana的操作
# 添加文檔 PUT phone/_doc/1 {"name":"小甜","age":18,"address":"小米5G手機" }PUT phone/_doc/2 {"name":"小米","age":18,"address":"華為5G手機" }PUT phone/_doc/3 {"name":"小付","age":18,"address":"小米4G手機" }PUT phone/_doc/4 {"name":"小付","age":18,"address":"重慶" }# 查詢所有 GET phone/_search# term 詞條查詢 詞條完全匹配 GET phone/_search {"query": {"term": {"address": {"value": "重慶"}}} }# match 先回對查詢的字符串進行分詞,在查詢,求并集GET phone/_search {"query": {"match": {"address": "華為手機"}} }# 查詢映射 GET xiaofu_index/_mapping# 查詢所有 GET xiaofu_index/_search批量操作-腳本
GET phone/_search# 批量操作-腳本 # 刪除4號記錄 # 添加8號記錄 # 修改2號記錄名稱為紅米 POST _bulk {"delete":{"_index":"phone","_id":"4"}} {"create":{"_index":"phone","_id":"8"}} {"name":"呵呵","age":58,"address":"重慶"} {"update":{"_index":"phone","_id":"2"}} {"doc":{"name":"紅米"}}批量操作-JavaAPI
//大量插入數據@Testvoid testBulkRequest() throws IOException {//創建大批量請求,整合所有的請求操作的BulkRequest bulkRequest = new BulkRequest();User user = new User("小花", 8);User user2 = new User("小離", 8);User user3 = new User("小昂", 8);User user4 = new User("小?", 9);ArrayList<User> users = new ArrayList<>();users.add(user4);users.add(user3);users.add(user2);users.add(user);//遍歷集合,循環插入到bulkRequest中for (int i = 0; i < users.size(); i++) {//循環插入,使用鏈式編程bulkRequest.add(new IndexRequest("xiaofu_index").id("" + (i + 1)).source(new ObjectMapper().writeValueAsString(users.get(i)), XContentType.JSON));}//發送請求BulkResponse bulk = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);System.out.println(bulk.status());//ok}//批量對文檔進行增刪改@Testvoid testBulkRequest02() throws IOException {/*# 批量操作-腳本# 刪除3號記錄# 添加8號記錄# 修改2號記錄名稱為紅米*///創建大批量請求,整合所有的請求操作的BulkRequest bulkRequest = new BulkRequest();//刪除3號記錄//添加6號記錄//修改2號記錄名稱為小米HashMap<String, Object> map6 = new HashMap<>();map6.put("name","六號");HashMap<String, Object> map2 = new HashMap<>();map2.put("name","小米");//執行批量操作(傳遞json) 使用鏈式編程bulkRequest.add(new DeleteRequest("phone","3"))//刪除3號記錄.add(new IndexRequest("phone").id("6").source(new ObjectMapper().writeValueAsString(map6),XContentType.JSON))//添加8號記錄.add(new UpdateRequest("phone","2").doc(new ObjectMapper().writeValueAsString(map2),XContentType.JSON));//修改2號記錄名稱為USer小米//執行批量操作(傳遞map) 使用鏈式編程 // bulkRequest.add(new DeleteRequest("phone","3")) // .add(new IndexRequest("phone").id("6").source(map6)) // .add(new UpdateRequest("phone","2").doc(map2));//發送請求BulkResponse bulk = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);System.out.println(bulk.status());//ok}//批量從數據庫中添加數據@Testvoid testBulkRequest03() throws IOException {//創建大批量請求,整合所有的請求操作的BulkRequest bulkRequest = new BulkRequest();//使用MyBatis-plus 查詢的//查詢數據庫中的所有goods信息List<Goods> goods = goodsMapper.selectList(null); // //分頁查詢需要這個類,我們就new出來,傳遞當前頁與每頁條數 // Page<Goods> goodsPage = new Page<>(1,10); // // //Wrapper 沒有就給null // Page<Goods> goodsPages = goodsMapper.selectPage(goodsPage, null); // // List<Goods> goods = goodsPages.getRecords();//遍歷for (Goods good : goods) {//將字符串轉成map // Map map = new ObjectMapper().readValue(good.getSpec(), Map.class); // good.setSpecMap(map);bulkRequest.add(new IndexRequest("goods").id(good.getId()+"").source(new ObjectMapper().writeValueAsString(good),XContentType.JSON));}//發送請求BulkResponse bulk = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);System.out.println(bulk.status());//ok}matchAll查詢-腳本
測試這個需要先準備大量數據
matchAll查詢-JavaAPI
/*** 查詢所有* 1. matchAll* 2. 將查詢結果封裝為Goods對象,裝載到List中* 3. 分頁。默認顯示10條*/@Testpublic void testMatchAll() throws IOException {//創建查詢請求對象,指定查詢的索引名稱SearchRequest searchRequest = new SearchRequest("goods");//創建查詢條件構造器SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();//指定查詢條件,查詢條件是使用條件構造器制作的 QueryBuilders.matchAllQuery() 查詢所有文檔searchSourceBuilder.query(QueryBuilders.matchAllQuery());//設置查詢的條件//添加分頁信息,指定查詢100條數據searchSourceBuilder.from(0);searchSourceBuilder.size(100);//添加查詢條件構建器 SearchSourceBuildersearchRequest.source(searchSourceBuilder);//查詢,獲取查詢結果SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);// 獲取命中對象 SearchHitsSearchHits responseHits = searchResponse.getHits();//獲取總條數long value = responseHits.getTotalHits().value;System.out.println("總記錄數:"+value);//獲取Hits數據 數組SearchHit[] hits = responseHits.getHits();//創建一個數組來存儲我們查詢出的json數據ArrayList<Goods> goodsArrayList = new ArrayList<>();for (SearchHit hit : hits) {//獲取查詢出的數據的json對象String sourceAsString = hit.getSourceAsString();//轉成goods對象Goods goods = new ObjectMapper().readValue(sourceAsString, Goods.class);//添加goodsArrayList.add(goods);}//遍歷輸出一下for (Goods goods : goodsArrayList) {System.out.println(goods);}}term查詢-腳本
# term查詢 不會對查詢條件進行分詞,完全匹配才能查出來 GET goods/_search {"query": {"term": {"title": {"value": "華為"}}} }term查詢-JavaAPI
//查詢 term查詢:不會對查詢條件進行分詞。@Testvoid testSearch() throws IOException {SearchRequest searchRequest = new SearchRequest("goods");//構建搜索條件SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();//使用QueryBuilders工具類 term 精確匹配TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("title", "小米"); // QueryBuilders.matchQuery() 匹配所有SearchSourceBuilder query = searchSourceBuilder.query(termQueryBuilder);//指定查詢條件,查詢條件是使用條件構造器制作的searchRequest.source(query);//發送SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);//查詢結果System.out.println(new ObjectMapper().writeValueAsString(search.getHits()));System.out.println("================");for (SearchHit hit : search.getHits().getHits()) {System.out.println(hit.getSourceAsMap());}}match查詢-腳本
# match查詢 #? 會對查詢條件進行分詞。 #? 然后將分詞后的查詢條件和詞條進行等值匹配 #? 默認取并集(OR)# 使用match查詢出華為手機 GET goods/_search {"query": {"match": {"title": "華為手機"}} }# 默認取并集(OR) GET goods/_search {"query": {"match": {"title": {"query": "華為手機","operator": "and"}}} }match查詢-JavaAPI
/*** matchQuery:詞條分詞查詢*/@Testpublic void testMatchQuery() throws IOException {//創建查詢請求SearchRequest searchRequest = new SearchRequest("goods");//創建查詢條件構造器SearchSourceBuilder sourceBulider = new SearchSourceBuilder();//設置查詢的參數 使用鏈式編程設置參數 operator(Operator.AND)//求并集sourceBulider.query(QueryBuilders.matchQuery("title","華為手機").operator(Operator.AND));//將查詢條件構造交給查詢請求對象searchRequest.source(sourceBulider);//設置返回的分頁數sourceBulider.from(0);sourceBulider.size(20);//發送查詢請求SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);//獲取查詢出的結果SearchHits searchHits = searchResponse.getHits();//獲取記錄數long value = searchHits.getTotalHits().value;System.out.println("總記錄數:"+value);List<Goods> goodsList = new ArrayList<>();SearchHit[] hits = searchHits.getHits();for (SearchHit hit : hits) {String sourceAsString = hit.getSourceAsString();//轉為javaGoods goods = new ObjectMapper().readValue(sourceAsString,Goods.class);goodsList.add(goods);}for (Goods goods : goodsList) {System.out.println(goods);}}模糊查詢-腳本
wildcard查詢:會對查詢條件進行分詞。還可以使用通配符 ?(任意單個字符) 和 * (0個或多個字符)
regexp查詢:正則查詢
prefix查詢:前綴查詢
模糊查詢-JavaAPI
/*** 模糊查詢:WildcardQuery*/@Testpublic void testWildcardQuery() throws IOException {SearchRequest searchRequest = new SearchRequest("goods");SearchSourceBuilder sourceBulider = new SearchSourceBuilder();//設置莫慌查詢sourceBulider.query(QueryBuilders.wildcardQuery("title","華?"));searchRequest.source(sourceBulider);SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);SearchHits searchHits = searchResponse.getHits();//獲取記錄數long value = searchHits.getTotalHits().value;System.out.println("總記錄數:"+value);List<Goods> goodsList = new ArrayList<>();SearchHit[] hits = searchHits.getHits();for (SearchHit hit : hits) {String sourceAsString = hit.getSourceAsString();//轉為javaGoods goods = new ObjectMapper().readValue(sourceAsString,Goods.class);goodsList.add(goods);}for (Goods goods : goodsList) {System.out.println(goods);}}/*** 模糊查詢:regexpQuery*/@Testpublic void testRegexpQuery() throws IOException {SearchRequest searchRequest = new SearchRequest("goods");SearchSourceBuilder sourceBulider = new SearchSourceBuilder();//設置莫慌查詢sourceBulider.query(QueryBuilders.regexpQuery("title","\\w+(.)*"));searchRequest.source(sourceBulider);SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);SearchHits searchHits = searchResponse.getHits();//獲取記錄數long value = searchHits.getTotalHits().value;System.out.println("總記錄數:"+value);List<Goods> goodsList = new ArrayList<>();SearchHit[] hits = searchHits.getHits();for (SearchHit hit : hits) {String sourceAsString = hit.getSourceAsString();//轉為javaGoods goods = new ObjectMapper().readValue(sourceAsString,Goods.class);goodsList.add(goods);}for (Goods goods : goodsList) {System.out.println(goods);}}/*** 模糊查詢:perfixQuery*/@Testpublic void testPrefixQuery() throws IOException {SearchRequest searchRequest = new SearchRequest("goods");SearchSourceBuilder sourceBulider = new SearchSourceBuilder();// PrefixQueryBuilder query = QueryBuilders.prefixQuery("brandName", "三");sourceBulider.query(QueryBuilders.prefixQuery("brandName","金"));searchRequest.source(sourceBulider);SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);SearchHits searchHits = searchResponse.getHits();//獲取記錄數long value = searchHits.getTotalHits().value;System.out.println("總記錄數:"+value);List<Goods> goodsList = new ArrayList<>();SearchHit[] hits = searchHits.getHits();for (SearchHit hit : hits) {String sourceAsString = hit.getSourceAsString();//轉為javaGoods goods =new ObjectMapper().readValue(sourceAsString,Goods.class);goodsList.add(goods);}for (Goods goods : goodsList) {System.out.println(goods);}}范圍查詢-腳本
range 范圍查詢:查找指定字段在指定范圍內包含值
# 范圍查詢 # gt 大于 lt 小于 # gte 大于等于 lte 小于等于 # sort 排序GET goods/_search {"query": {"range": {"price": {"gte": 1000,"lte": 2000}}},"sort": [{"price": {"order": "desc"}}] }范圍查詢-JavaAPI
/*** 1. 范圍查詢:rangeQuery* 2. 排序*/@Testpublic void testRangeQuery() throws IOException {SearchRequest searchRequest = new SearchRequest("goods");SearchSourceBuilder sourceBulider = new SearchSourceBuilder();// //范圍查詢 // RangeQueryBuilder query = QueryBuilders.rangeQuery("price"); // // //指定下限 // query.gte(2000); // //指定上限 // query.lte(3000);//使用鏈式編程 設置范圍查詢sourceBulider.query(QueryBuilders.rangeQuery("price").gte(1000).lte(2000));//排序sourceBulider.sort("price", SortOrder.DESC);searchRequest.source(sourceBulider);SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);SearchHits searchHits = searchResponse.getHits();//獲取記錄數long value = searchHits.getTotalHits().value;System.out.println("總記錄數:"+value);List<Goods> goodsList = new ArrayList<>();SearchHit[] hits = searchHits.getHits();for (SearchHit hit : hits) {String sourceAsString = hit.getSourceAsString();//轉為javaGoods goods = new ObjectMapper().readValue(sourceAsString,Goods.class);goodsList.add(goods);}for (Goods goods : goodsList) {System.out.println(goods);}}queryString查詢-腳本
queryString:
? 會對查詢條件進行分詞。
? 然后將分詞后的查詢條件和詞條進行等值匹配
? 默認取并集(OR)
? 可以指定多個查詢字段
queryString查詢-JavaAPI
/*** queryString*/@Testpublic void testQueryStringQuery() throws IOException {SearchRequest searchRequest = new SearchRequest("goods");SearchSourceBuilder sourceBulider = new SearchSourceBuilder();//queryString // QueryStringQueryBuilder query = QueryBuilders.queryStringQuery("華為手機") // .field("title").field("categoryName").field("brandName") // .defaultOperator(Operator.AND);//queryString 查詢,默認使用OR并集 使用AND 查詢分詞交集sourceBulider.query(QueryBuilders.queryStringQuery("華為 AND 手機").field("title").field("categoryName").field("brandName"));searchRequest.source(sourceBulider);SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);SearchHits searchHits = searchResponse.getHits();//獲取記錄數long value = searchHits.getTotalHits().value;System.out.println("總記錄數:"+value);List<Goods> goodsList = new ArrayList<>();SearchHit[] hits = searchHits.getHits();for (SearchHit hit : hits) {String sourceAsString = hit.getSourceAsString();//轉為javaGoods goods = new ObjectMapper().readValue(sourceAsString,Goods.class);goodsList.add(goods);}for (Goods goods : goodsList) {System.out.println(goods);}}布爾查詢-腳本
boolQuery:對多個查詢條件連接。連接方式:
? must(and):條件必須成立
? must_not(not):條件必須不成立
? should(or):條件可以成立
? filter:條件必須成立,性能比must高。不會計算得分
布爾查詢-JavaAPI
/*** 布爾查詢:boolQuery* 1. 查詢品牌名稱為:華為* 2. 查詢標題包含:手機* 3. 查詢價格在:2000-3000*/@Testpublic void testBoolQuery() throws IOException {SearchRequest searchRequest = new SearchRequest("goods");SearchSourceBuilder sourceBulider = new SearchSourceBuilder();//1.構建boolQuery // BoolQueryBuilder query = QueryBuilders.boolQuery(); // // //2.構建各個查詢條件 // //2.1 查詢品牌名稱為:華為 // QueryBuilder termQuery = QueryBuilders.termQuery("brandName","華為"); // query.must(termQuery); // // //2.2. 查詢標題包含:手機 // QueryBuilder matchQuery = QueryBuilders.matchQuery("title","手機"); // query.filter(matchQuery); // // //2.3 查詢價格在:2000-3000 // QueryBuilder rangeQuery = QueryBuilders.rangeQuery("price"); // ((RangeQueryBuilder) rangeQuery).gte(2000); // ((RangeQueryBuilder) rangeQuery).lte(3000); // query.filter(rangeQuery);//3.使用boolQuery連接 鏈式編程sourceBulider.query(QueryBuilders.boolQuery().must(QueryBuilders.termQuery("brandName","華為")).must(QueryBuilders.matchQuery("title","手機")).filter(QueryBuilders.rangeQuery("price").gte(2000).lte(3000)));searchRequest.source(sourceBulider);SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);SearchHits searchHits = searchResponse.getHits();//獲取記錄數long value = searchHits.getTotalHits().value;System.out.println("總記錄數:"+value);List<Goods> goodsList = new ArrayList<>();SearchHit[] hits = searchHits.getHits();for (SearchHit hit : hits) {String sourceAsString = hit.getSourceAsString();//轉為javaGoods goods = new ObjectMapper().readValue(sourceAsString,Goods.class);goodsList.add(goods);}for (Goods goods : goodsList) {System.out.println(goods);}}聚合查詢-腳本
? 指標聚合:相當于MySQL的聚合函數。max、min、avg、sum等
? 桶聚合:相當于MySQL的 group by 操作。不要對text類型的數據進行分組,會失敗。
聚合查詢-JavaAPI
/*** 聚合查詢:桶聚合,分組查詢* 1. 查詢title包含手機的數據* 2. 查詢品牌列表*/@Testpublic void testAggQuery() throws IOException {//創建查詢請求對象SearchRequest searchRequest = new SearchRequest("goods");//構建查詢對象SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();//設置查詢條件searchSourceBuilder.query(QueryBuilders.matchQuery("title","手機"));// 2. 查詢品牌列表/*參數:1. 自定義的名稱goods_brands,將來用于獲取數據2. 分組的字段*/searchSourceBuilder.aggregation(AggregationBuilders.terms("goods_brands").field("brandName").size(100));//給查詢請求傳遞構建對象searchRequest.source(searchSourceBuilder);//發送請求 得到響應對象SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);//獲取命中結果SearchHits hits = searchResponse.getHits();//獲取總命中數long value = hits.getTotalHits().value;System.out.println("總記錄數:"+value);//獲取命中結果集合SearchHit[] hitsHits = hits.getHits();//創建一個集合來存儲命中結果的每個對象ArrayList<Goods> goodsArrayList = new ArrayList<>();//遍歷命中結果for (SearchHit hitsHit : hitsHits) {//獲取每條命中結果的json字符串String sourceAsString = hitsHit.getSourceAsString();//轉成對象Goods goods = new ObjectMapper().readValue(sourceAsString, Goods.class);//添加到集合goodsArrayList.add(goods);}//遍歷集合輸出for (Goods goods : goodsArrayList) {System.out.println(goods);}System.out.println("-------------獲取聚合結果-----------------");Aggregations aggregations = searchResponse.getAggregations();//獲取結果mapMap<String, Aggregation> asMap = aggregations.getAsMap();//獲取聚合Terms goodsBrands = (Terms) asMap.get("goods_brands");//List<? extends Terms.Bucket> buckets = goodsBrands.getBuckets();//創建一個集合來存儲分組后的數據ArrayList<Object> objects = new ArrayList<>();for (Terms.Bucket bucket : buckets) {Object key = bucket.getKey();objects.add(key);}//輸出分組數據for (Object object : objects) {System.out.println(object);}}高亮查詢-腳本
高亮三要素:
? 高亮字段
? 前綴
? 后綴
高亮查詢-JavaAPI
/*** 高亮查詢:* 1. 設置高亮* * 高亮字段* * 前綴* * 后綴* 2. 將高亮了的字段數據,替換原有數據*/@Testpublic void testHighLightQuery() throws IOException {//創建查詢請求SearchRequest searchRequest = new SearchRequest("goods");//創建查詢條件構造器SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();//查詢title包含手機的數據searchSourceBuilder.query(QueryBuilders.matchQuery("title","手機"));//創建高亮構造,設置高亮HighlightBuilder highlightBuilder = new HighlightBuilder();highlightBuilder.field("title").preTags("<font color='red'>").postTags("</font>");//設置高亮searchSourceBuilder.highlighter(highlightBuilder);//設置條件searchRequest.source(searchSourceBuilder);//發送請求SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);//獲取命中結果SearchHits hits = search.getHits();//裝GoodsArrayList<Goods> goodsArrayList = new ArrayList<>();//獲取總記錄數long value = hits.getTotalHits().value;System.out.println("總記錄數:"+value);//遍歷for (SearchHit hit : hits) {String sourceAsString = hit.getSourceAsString();Goods goods = new ObjectMapper().readValue(sourceAsString, Goods.class);goodsArrayList.add(goods);}//輸出for (Goods goods : goodsArrayList) {System.out.println(goods);}}總結
以上是生活随笔為你收集整理的ElasticSearch,docker 安装ElasticSearch,Springboot 使用 ElasticSearch JavaAPI的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: RabbitMQ,Springboot整
- 下一篇: java美元兑换,(Java实现) 美元