Java微服务篇4——Elastic search
Java微服務篇4——Elastic search
1、Elastic search安裝配置
Elastic search官方:https://www.elastic.co/cn/products/elasticsearch
Elastic search6.2.4 百度云:https://pan.baidu.com/s/1JyQok8Nija4gYhcjh-HWcw提取碼:isa2
解壓即可
在config/elasticsearch.yml修改
# ----------------------------------- Paths ------------------------------------ # # Path to directory where to store the data (separate multiple locations by comma): # path.data: /path/to/data # # Path to log files: # path.logs: /path/to/logs啟動bin目錄下的elasticsearch.bat/elasticsearch.sh
訪問
http://localhost:9200/2、kibana安裝
Kibana是一個基于Node.js的Elasticsearch索引庫數據統計工具,可以利用Elasticsearch的聚合功能, 生成各種圖表,如柱形圖,線狀圖,餅圖等。 而且還提供了操作Elasticsearch索引數據的控制臺
kibana6.2.4 百度云:https://pan.baidu.com/s/1AlD34ZYvHqtVwaapRh3tPA提取碼:p8gr
在config/kibana.yml修改
elasticsearch.url: "http://localhost:9200"3、ik分詞器
elasticsearch-analysis-ik-6.2.4 百度云:https://pan.baidu.com/s/1L4_fQIgLmLoLpKL8sXAAFw提取碼:8k05
解壓elasticsearch-analysis-ik-6.2.4.zip后,將解壓后的文件夾拷貝到elasticsearch-6.2.4\plugins 下,并重命名文件夾為ik
重啟即可
測試
GET /_analyze {"text": "我是中國人" } GET /_analyze {"analyzer": "ik_max_word","text": "我是中國人" } GET /_analyze {"analyzer": "ik_min_word","text": "我是中國人" }4、elasticsearch-head
elasticsearch-head 百度云:https://pan.baidu.com/s/1JsOvr64gb5xNbkPPJafyag提取碼:6khj
5、elastic search操作
映射屬性數據類型
| 核心類型 | 字符串類型 | text | 當一個字段是要被全文搜索的,比如Email內容、產品描述,應該使用text類型 設置text類型以后,字段內容會被分析,在生成倒排索引以前,字符串會被分析器分成一個一個詞項 text類型的字段不用于排序,很少用于聚合 |
| keyword | keyword類型適用于索引結構化的字段,比如email地址、主機名、狀態碼和標簽 如果字段需要進行過濾(比如查找已發布博客中status屬性為published的文章)、排序、聚合 keyword類型的字段只能通過精確值搜索到 | ||
| 整數類型 | byte | -128~127 | |
| short | -32768~32767 | ||
| integer | -231~231-1 | ||
| long | -263~263-1 | ||
| 浮點類型 | float | 32位單精度IEEE 754浮點類型 | |
| double | 64位雙精度IEEE 754浮點類型 | ||
| half_float | 16位半精度IEEE 754浮點類型 | ||
| scaled_float | 縮放類型的的浮點數 | ||
| 邏輯類型 | boolean | true,false | |
| 日期類型 | date | (1)日期格式的字符串,比如 “2018-01-13” 或 “2018-01-13 12:10:30” (2)long類型的毫秒數 (3)integer的秒數seconds-since-the-epoch | |
| 范圍類型 | range | ||
| 二進制類型 | binary | 進制字段是指用base64來表示索引中存儲的二進制數據,可用來存儲二進制形式的數據,例如圖像 | |
| 復合類型 | 數組類型 | array | (1)字符數組: [ “one”, “two” ] (2)整數數組: productid:[ 1, 2 ] (3)對象(文檔)數組: “user”:[ { “name”: “Mary”, “age”: 12 }, { “name”: “John”, “age”: 10 }] |
| 對象類型 | object | JSON對象,文檔會包含嵌套的對象 | |
| 嵌套類型 | nested | 用于JSON對象數組 | |
| 地理類型 | 地理坐標類型 | geo_point | 緯度/經度積分 |
| 地理地圖 | geo_shape | 用于多邊形等復雜形狀 | |
| 特殊類型 | IP類型 | ip | 用于存儲IPv4或者IPv6的地址 |
| 范圍類型 | completion | 提供自動完成建議 | |
| 令牌計數類型 | token_count | 計算字符串中令牌的數量 |
index
是否被索引
index的默認值就是true,也就是說你不進行任何配置,所有字段都會被索引,有些字段是我們不希望被索引的,比如商品的圖片信息(URL),就需要手動設置index為false
stroe
是否額外存儲
在lucene里,如果一個字段的store設置為false,那么在文檔列表中就不會有這個字段的 值,用戶的搜索結果中不會顯示出來,但是在Elasticsearch中,即便store設置為false,也可以搜索到結果
原因是Elasticsearch在創建文檔索引時,會將文檔中的原始數據備份,保存到一個叫做 _source 的屬性 中。而且我們可以通過過濾 _source 來選擇哪些要顯示,哪些不顯示
如果設置store為true,就會在 _source 以外額外存儲一份數據,多余,因此一般我們都會將store設 置為false,事實上,store的默認值就是false
在某些情況下,這對 store 某個領域可能是有意義的。例如,如果您的文檔包含一個 title ,一個 date 和一個非常大的 content 字段,則可能只想檢索the title 和the date 而不必從一個大 _source 字段中提取這些字段
boost
網站權重:網站權重是指搜索引擎給網站(包括網頁)賦予一定的權威值,對網站(含網頁)權威的評估評價。一 個網站權重越高,在搜索引擎所占的份量越大,在搜索引擎排名就越好。提高網站權重,不但利于網站(包括網 頁)在搜索引擎的排名更靠前,還能提高整站的流量,提高網站信任度。所以提高網站的權重具有相當重要的意 義。 權重即網站在SEO中的重要性,權威性。英文:Page Strength。
- 權重不等于排名
- 權重對排名有著 非常大的影響
- 整站權重的提高有利于內頁的排名
5.1、庫操作(database)
# 添加索引庫 PUT /索引庫名 # 獲取索引庫信息 GET /索引庫名 # 刪除索引庫 DELETE /索引庫名5.2、類型及映射操作(表)
創建數據庫表需要設置字段約束,索引庫也一樣,在創建索引庫的類型時,需要知道這個類型下 有哪些字段,每個字段有哪些約束信息,這就叫做 字段映射(mapping)
# 添加類型及映射1(向索引庫追加類型及映射) PUT winkto/_mapping/goods {"properties": {"title": {"type": "text","analyzer": "ik_max_word"},"images": {"type": "keyword","index": "false"},"price": {"type": "float"}} } # 添加類型及映射2(在索引庫創建時添加類型及映射) PUT /winkto2 {"settings": {},"mappings": {"goods": {"properties": {"title": {"type": "text","analyzer": "ik_max_word"}}}} } # 查看類型及映射 GET winkto/_mapping GET winkto/_mapping/goods5.3、追加數據
# 追加數據(隨機id) POST /winkto/goods/ {"title":"小米10","images":"http://image.lagou.com/12479122.jpg","price":2699.00 } # 追加數據(指定id) POST /winkto/goods/sadhsahduashfusahdi {"title":"華為","images":"http://image.lagou.com/12479122.jpg","price":4699.00 } # 獲取數據 GET /winkto/goods/xqurVHsB1mHhNfuBSw0p5.4、刪除數據
DELETE /winkto/goods/sadhsahduashfusahdi5.5、查詢
語法
GET /索引庫名/_search {"query":{"查詢類型":{"查詢條件":"查詢條件值"}} }5.5.1、查詢所有
GET /winkto/_search {"query":{"match_all":{}} } {"took": 2,"timed_out": false,"_shards": {"total": 5,"successful": 5,"skipped": 0,"failed": 0},"hits": {"total": 2,"max_score": 1,"hits": [{"_index": "winkto","_type": "goods","_id": "xqurVHsB1mHhNfuBSw0p","_score": 1,"_source": {"title": "小米10","images": "http://image.lagou.com/12479122.jpg","price": 2699}},{"_index": "winkto","_type": "goods","_id": "kBFMWHsBy-koX7e_VW4W","_score": 1,"_source": {"title": "華為pro30","images": "http://image.lagou.com/12479122.jpg","price": 5699}}]} }5.5.2、條件查詢
GET /winkto/_search {"query":{"match":{"title": "小米"}} } {"took": 16,"timed_out": false,"_shards": {"total": 5,"successful": 5,"skipped": 0,"failed": 0},"hits": {"total": 1,"max_score": 0.2876821,"hits": [{"_index": "winkto","_type": "goods","_id": "xqurVHsB1mHhNfuBSw0p","_score": 0.2876821,"_source": {"title": "小米10","images": "http://image.lagou.com/12479122.jpg","price": 2699}}]} }match 類型查詢,會把查詢條件進行分詞,然后進行查詢,多個詞條之間是or的關系
GET /winkto/_search {"query":{"match":{"title": "小米華為"}} } {"took": 355,"timed_out": false,"_shards": {"total": 5,"successful": 5,"skipped": 0,"failed": 0},"hits": {"total": 2,"max_score": 0.2876821,"hits": [{"_index": "winkto","_type": "goods","_id": "xqurVHsB1mHhNfuBSw0p","_score": 0.2876821,"_source": {"title": "小米10","images": "http://image.lagou.com/12479122.jpg","price": 2699}},{"_index": "winkto","_type": "goods","_id": "kBFMWHsBy-koX7e_VW4W","_score": 0.2876821,"_source": {"title": "華為pro30","images": "http://image.lagou.com/12479122.jpg","price": 5699}}]} }但是有些時候我們希望分詞關系為and
GET /winkto/_search {"query":{"match":{"title": {"query": "小米華為","operator": "and"}}} } {"took": 8,"timed_out": false,"_shards": {"total": 5,"successful": 5,"skipped": 0,"failed": 0},"hits": {"total": 1,"max_score": 0.5753642,"hits": [{"_index": "winkto","_type": "goods","_id": "kRFWWHsBy-koX7e_DW5_","_score": 0.5753642,"_source": {"title": "小米華為plusplus","images": "http://image.lagou.com/12479122.jpg","price": 2699}}]} }5.5.3、詞條匹配
term 查詢被用于精確值 匹配,這些精確值可能是數字、時間、布爾或者那些未分詞的字符 串,keyword類型的字符串
GET /winkto/_search {"query":{"term": {"price": 2699}} } {"took": 7,"timed_out": false,"_shards": {"total": 5,"successful": 5,"skipped": 0,"failed": 0},"hits": {"total": 2,"max_score": 1,"hits": [{"_index": "winkto","_type": "goods","_id": "xqurVHsB1mHhNfuBSw0p","_score": 1,"_source": {"title": "小米10","images": "http://image.lagou.com/12479122.jpg","price": 2699}},{"_index": "winkto","_type": "goods","_id": "kRFWWHsBy-koX7e_DW5_","_score": 1,"_source": {"title": "小米華為plusplus","images": "http://image.lagou.com/12479122.jpg","price": 2699}}]} }5.5.4、布爾組合
bool 把各種其它查詢通過 must (與)、 must_not (非)、 should (或)的方式進行組合
GET /winkto/_search {"query":{"bool": {"must": [{"match": {"title": "小米"}}],"must_not": [{"match": {"title": "華為"}}],"should": [{"match": {"title": "10"}}]}} } {"took": 2,"timed_out": false,"_shards": {"total": 5,"successful": 5,"skipped": 0,"failed": 0},"hits": {"total": 1,"max_score": 0.5753642,"hits": [{"_index": "winkto","_type": "goods","_id": "xqurVHsB1mHhNfuBSw0p","_score": 0.5753642,"_source": {"title": "小米10","images": "http://image.lagou.com/12479122.jpg","price": 2699}}]} }5.5.5、范圍查詢
GET /winkto/_search {"query":{"range": {"price": {"gte": 2000,"lte": 6000}}} } {"took": 4,"timed_out": false,"_shards": {"total": 5,"successful": 5,"skipped": 0,"failed": 0},"hits": {"total": 3,"max_score": 1,"hits": [{"_index": "winkto","_type": "goods","_id": "xqurVHsB1mHhNfuBSw0p","_score": 1,"_source": {"title": "小米10","images": "http://image.lagou.com/12479122.jpg","price": 2699}},{"_index": "winkto","_type": "goods","_id": "kBFMWHsBy-koX7e_VW4W","_score": 1,"_source": {"title": "華為pro30","images": "http://image.lagou.com/12479122.jpg","price": 5699}},{"_index": "winkto","_type": "goods","_id": "kRFWWHsBy-koX7e_DW5_","_score": 1,"_source": {"title": "小米華為plusplus","images": "http://image.lagou.com/12479122.jpg","price": 2699}}]} }5.6、結果過濾
默認情況下,elasticsearch在搜索的結果中,會把文檔中保存在 _source 的所有字段都返回。但有時只想獲取其中的部分字段,此時可以添加 _source 的過濾
5.6.1、直接指定字段
GET /winkto/_search {"_source": ["title","price"], "query":{"match": {"title": "小米"}} } {"took": 9,"timed_out": false,"_shards": {"total": 5,"successful": 5,"skipped": 0,"failed": 0},"hits": {"total": 2,"max_score": 0.2876821,"hits": [{"_index": "winkto","_type": "goods","_id": "xqurVHsB1mHhNfuBSw0p","_score": 0.2876821,"_source": {"price": 2699,"title": "小米10"}},{"_index": "winkto","_type": "goods","_id": "kRFWWHsBy-koX7e_DW5_","_score": 0.2876821,"_source": {"price": 2699,"title": "小米華為plusplus"}}]} }5.6.2、includes和excludes
- includes:來指定想要顯示的字段
- excludes:來指定不想要顯示的字段
5.6.3、Filter
GET /winkto/_search {"query":{"bool": {"must": [{"match": {"title": "小米"}}],"filter": {"range": {"price": {"gte": 1000,"lte": 3000}}}}} } {"took": 1,"timed_out": false,"_shards": {"total": 5,"successful": 5,"skipped": 0,"failed": 0},"hits": {"total": 2,"max_score": 0.2876821,"hits": [{"_index": "winkto","_type": "goods","_id": "xqurVHsB1mHhNfuBSw0p","_score": 0.2876821,"_source": {"title": "小米10","images": "http://image.lagou.com/12479122.jpg","price": 2699}},{"_index": "winkto","_type": "goods","_id": "kRFWWHsBy-koX7e_DW5_","_score": 0.2876821,"_source": {"title": "小米華為plusplus","images": "http://image.lagou.com/12479122.jpg","price": 2699}}]} }如果一次查詢只有過濾,沒有查詢條件,不希望進行評分,可以使用 constant_score 取代只有 filter 語句的 bool 查詢
GET /winkto/_search {"query":{"constant_score": {"filter": {"range": {"price": {"gte": 1000,"lte": 3000}}}}} } {"took": 4,"timed_out": false,"_shards": {"total": 5,"successful": 5,"skipped": 0,"failed": 0},"hits": {"total": 2,"max_score": 1,"hits": [{"_index": "winkto","_type": "goods","_id": "xqurVHsB1mHhNfuBSw0p","_score": 1,"_source": {"title": "小米10","images": "http://image.lagou.com/12479122.jpg","price": 2699}},{"_index": "winkto","_type": "goods","_id": "kRFWWHsBy-koX7e_DW5_","_score": 1,"_source": {"title": "小米華為plusplus","images": "http://image.lagou.com/12479122.jpg","price": 2699}}]} }5.7、排序
GET /winkto/_search {"query":{"match_all": {}},"sort": [{"price": {"order": "desc"}}] } {"took": 141,"timed_out": false,"_shards": {"total": 5,"successful": 5,"skipped": 0,"failed": 0},"hits": {"total": 3,"max_score": null,"hits": [{"_index": "winkto","_type": "goods","_id": "kBFMWHsBy-koX7e_VW4W","_score": null,"_source": {"title": "華為pro30","images": "http://image.lagou.com/12479122.jpg","price": 5699},"sort": [5699]},{"_index": "winkto","_type": "goods","_id": "xqurVHsB1mHhNfuBSw0p","_score": null,"_source": {"title": "小米10","images": "http://image.lagou.com/12479122.jpg","price": 2699},"sort": [2699]},{"_index": "winkto","_type": "goods","_id": "kRFWWHsBy-koX7e_DW5_","_score": null,"_source": {"title": "小米華為plusplus","images": "http://image.lagou.com/12479122.jpg","price": 2699},"sort": [2699]}]} }5.8、分頁
GET /winkto/_search {"query":{"match_all": {}},"from": 0,"size": 2 } {"took": 5,"timed_out": false,"_shards": {"total": 5,"successful": 5,"skipped": 0,"failed": 0},"hits": {"total": 3,"max_score": 1,"hits": [{"_index": "winkto","_type": "goods","_id": "xqurVHsB1mHhNfuBSw0p","_score": 1,"_source": {"title": "小米10","images": "http://image.lagou.com/12479122.jpg","price": 2699}},{"_index": "winkto","_type": "goods","_id": "kBFMWHsBy-koX7e_VW4W","_score": 1,"_source": {"title": "華為pro30","images": "http://image.lagou.com/12479122.jpg","price": 5699}}]} }5.9、高亮顯示
GET /winkto/_search {"query":{"match": {"title": "小米"}},"highlight": {"pre_tags": "<em>","post_tags": "</em>","fields": {"title": {}}} } {"took": 69,"timed_out": false,"_shards": {"total": 5,"successful": 5,"skipped": 0,"failed": 0},"hits": {"total": 2,"max_score": 0.2876821,"hits": [{"_index": "winkto","_type": "goods","_id": "xqurVHsB1mHhNfuBSw0p","_score": 0.2876821,"_source": {"title": "小米10","images": "http://image.lagou.com/12479122.jpg","price": 2699},"highlight": {"title": ["<em>小米</em>10"]}},{"_index": "winkto","_type": "goods","_id": "kRFWWHsBy-koX7e_DW5_","_score": 0.2876821,"_source": {"title": "小米華為plusplus","images": "http://image.lagou.com/12479122.jpg","price": 2699},"highlight": {"title": ["<em>小米</em>華為plusplus"]}}]} }5.10、聚合
聚合可以讓我們極其方便的實現對數據的統計、分析
- 桶(group by):是按照某種方式對數據進行分組,每一組數據在ES中稱為一個 桶
- 度量(聚合的結果):求平均值、最大、最小、求和等
預準備
PUT /car {"mappings": {"orders": {"properties": {"color": {"type": "keyword"},"make": {"type": "keyword"}}}} } POST /car/orders/_bulk { "index": {}} { "price" : 10000, "color" : "紅", "make" : "本田", "sold" : "2020-10-28" } { "index": {}} { "price" : 20000, "color" : "紅", "make" : "本田", "sold" : "2020-11-05" } { "index": {}} { "price" : 30000, "color" : "綠", "make" : "福特", "sold" : "2020-05-18" } { "index": {}} { "price" : 15000, "color" : "藍", "make" : "豐田", "sold" : "2020-07-02" } { "index": {}} { "price" : 12000, "color" : "綠", "make" : "豐田", "sold" : "2020-08-19" } { "index": {}} { "price" : 20000, "color" : "紅", "make" : "本田", "sold" : "2020-11-05" } { "index": {}} { "price" : 80000, "color" : "紅", "make" : "寶馬", "sold" : "2020-01-01" } { "index": {}} { "price" : 25000, "color" : "藍", "make" : "福特", "sold" : "2020-02-12" }5.10.1、聚合為桶
GET /car/_search {"size": 0,"aggs": {"popular_colors": {"terms": {"field": "color"}}} } {"took": 48,"timed_out": false,"_shards": {"total": 5,"successful": 5,"skipped": 0,"failed": 0},"hits": {"total": 8,"max_score": 0,"hits": []},"aggregations": {"popular_colors": {"doc_count_error_upper_bound": 0,"sum_other_doc_count": 0,"buckets": [{"key": "紅","doc_count": 4},{"key": "綠","doc_count": 2},{"key": "藍","doc_count": 2}]}} }5.10.2、聚合操作
GET /car/_search {"size": 0,"aggs": {"popular_colors": {"terms": {"field": "color"},"aggs": {"avg_price": {"avg": {"field": "price"}}}}} } {"took": 8,"timed_out": false,"_shards": {"total": 5,"successful": 5,"skipped": 0,"failed": 0},"hits": {"total": 8,"max_score": 0,"hits": []},"aggregations": {"popular_colors": {"doc_count_error_upper_bound": 0,"sum_other_doc_count": 0,"buckets": [{"key": "紅","doc_count": 4,"avg_price": {"value": 32500}},{"key": "綠","doc_count": 2,"avg_price": {"value": 21000}},{"key": "藍","doc_count": 2,"avg_price": {"value": 20000}}]}} }6、Elastic search集群
6.1、集群解決的問題
- 單臺機器存儲容量有限,無法實現高存儲
- 單服務器容易出現單點故障,無法實現高可用
- 單服務的并發處理能力有限,無法實現高并發
6.2、數據分片
第一個問題就是數據量太大,單點存儲量有限的問題,可以把數據拆分成多份,每一份存儲到不同機器節點(node),從而實現減少每個節點數 據量的目的。這就是數據的分布式存儲,也叫做: 數據分片(Shard)
數據分片解決了海量數據存儲的問題,但是如果出現單點故障,那么分片數據就不再完整
給每個分片數據進行備 份,存儲到其它節點,防止數據丟失,這就是數據備份,也叫 數據副本(replica)
數據備份可以保證高可用,但是每個分片備份一份,所需要的節點數量就會翻一倍,成本實在是太高
為了在高可用和成本間尋求平衡,首先對數據分片,存儲到不同節點 然后對每個分片進行備份,放到對方節點,完成互相備份
6.3、集群搭建
node-0配置文件(node-1,node-2只需要修改node.name、http.port,transport.tcp.port,path.data,path.logs即可)
# ---------------------------------- Cluster ----------------------------------- # Use a descriptive name for your cluster: cluster.name: my-application # ------------------------------------ Node ------------------------------------ # Use a descriptive name for the node: node.name: node-0 # Add custom attributes to the node: #node.attr.rack: r1 # 是否可以為主節點 node.master: true # ----------------------------------- Paths ------------------------------------ # Path to directory where to store the data (separate multiple locations by comma): path.data: D:\es\elasticsearch-6.2.4-0\data # Path to log files: path.logs: D:\es\elasticsearch-6.2.4-0\data # ----------------------------------- Memory ----------------------------------- # Lock the memory on startup: #bootstrap.memory_lock: true # Make sure that the heap size is set to about half the memory available # on the system and that the owner of the process is allowed to use this # limit. # Elasticsearch performs poorly when the system is swapping the memory. # ---------------------------------- Network ----------------------------------- # Set the bind address to a specific IP (IPv4 or IPv6): network.host: 0.0.0.0 # Set a custom port for HTTP: http.port: 9200 # For more information, consult the network module documentation. # TCP協議對外端口 每個節點不一樣,默認:9300 transport.tcp.port: 9201 # --------------------------------- Discovery ---------------------------------- # Pass an initial list of hosts to perform discovery when new node is started: # The default list of hosts is ["127.0.0.1", "[::1]"] #discovery.zen.ping.unicast.hosts: ["host1", "host2"] # Prevent the "split brain" by configuring the majority of nodes (total number of master-eligible nodes / 2 + 1): #discovery.zen.minimum_master_nodes: # For more information, consult the zen discovery module documentation. discovery.zen.ping.unicast.hosts: ["127.0.0.1:9201","127.0.0.1:9301","127.0.0.1:9401"] discovery.zen.minimum_master_nodes: 2 # ---------------------------------- Gateway ----------------------------------- # Block initial recovery after a full cluster restart until N nodes are started: #gateway.recover_after_nodes: 3 # For more information, consult the gateway module documentation. # ---------------------------------- Various ----------------------------------- # Require explicit names when deleting indices: #action.destructive_requires_name: true # ---------------------------------- Http ----------------------------------- #允許跨域名訪問 http.cors.enabled: true #當設置允許跨域,默認為*,表示支持所有域名 http.cors.allow-origin: "*"
創建索引winkto
7、Elastic search API
預準備
PUT /winkto {"settings": {"number_of_shards": 3,"number_of_replicas": 1},"mappings": {"items":{"properties": {"id": {"type": "keyword"},"title":{"type": "text","analyzer": "ik_max_word"},"category":{"type": "keyword"},"brand": {"type": "keyword"},"images":{"type": "keyword","index": false},"price":{"type": "double"}}}} }7.1、添加數據
導入依賴
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-logging</artifactId></dependency><!--ES高級Rest Client--><dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId><version>6.5.4</version></dependency><dependency><groupId>org.elasticsearch</groupId><artifactId>elasticsearch</artifactId><version>6.5.4</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId></dependency> </dependencies>實體類
public class Product {private Long id;private String title;private String category;private String brand;private Double price;private String images; }config
@Configuration public class WinktoConfig {@Beanpublic ObjectMapper jackson(){return new ObjectMapper();} }測試
@SpringBootTest class ElasticSearchApplicationTests {@AutowiredObjectMapper jackson;@Testvoid contextLoadsinsert() throws IOException {// 初始化HighLevel客戶端RestHighLevelClient restHighLevelClient = new RestHighLevelClient(RestClient.builder(new HttpHost("127.0.0.1",9200),new HttpHost("127.0.0.1",9300),new HttpHost("127.0.0.1",9400)));// 文檔數據Product product = new Product(1L,"華為P50、新款發布","手機","華為",5999.9,"http://image.huawei.com/1.jpg");IndexRequest indexRequest = new IndexRequest("winkto", "items", product.getId().toString());indexRequest.source(jackson.writeValueAsString(product), XContentType.JSON);IndexResponse response = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);System.out.println(response);// 關閉客戶端restHighLevelClient.close();} }結果
IndexResponse[index=winkto,type=items,id=1,version=3,result=created,seqNo=2,primaryTerm=1,shards={"total":2,"successful":2,"failed":0}]7.2、查詢數據
@Test void contextLoadsSelect() throws IOException {// 初始化HighLevel客戶端RestHighLevelClient restHighLevelClient = new RestHighLevelClient(RestClient.builder(new HttpHost("127.0.0.1",9200),new HttpHost("127.0.0.1",9300),new HttpHost("127.0.0.1",9400)));GetRequest getRequest = new GetRequest("winkto","items","1");GetResponse documentFields = restHighLevelClient.get(getRequest,RequestOptions.DEFAULT);String sourceAsString = documentFields.getSourceAsString();Product product = jackson.readValue(sourceAsString, Product.class);System.out.println(product.toString());// 關閉客戶端restHighLevelClient.close(); } Product{id=1, title='華為P50、新款發布', category='手機', brand='華為', price=5999.9, images='http://image.huawei.com/1.jpg'}7.3、修改文檔
新增時,如果傳遞的id是已經存在的,則會完成修改操作,如果不存在,則是新增
7.4、刪除文檔
@Test void contextLoadsDelete() throws IOException {// 初始化HighLevel客戶端RestHighLevelClient restHighLevelClient = new RestHighLevelClient(RestClient.builder(new HttpHost("127.0.0.1",9200),new HttpHost("127.0.0.1",9300),new HttpHost("127.0.0.1",9400)));DeleteRequest deleteRequest = new DeleteRequest("winkto", "items", "1");DeleteResponse delete = restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);// 關閉客戶端restHighLevelClient.close(); }7.5、match_all
@Test void contextLoadsMatchAll() throws IOException {// 初始化HighLevel客戶端RestHighLevelClient restHighLevelClient = new RestHighLevelClient(RestClient.builder(new HttpHost("127.0.0.1",9200),new HttpHost("127.0.0.1",9300),new HttpHost("127.0.0.1",9400)));SearchRequest searchRequest = new SearchRequest();SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();searchSourceBuilder.query(QueryBuilders.matchAllQuery());searchRequest.source(searchSourceBuilder);SearchResponse search = restHighLevelClient.search(searchRequest);SearchHits hits = search.getHits();SearchHit[] hits1 = hits.getHits();for (SearchHit documentFields : hits1) {String sourceAsString = documentFields.getSourceAsString();Product product = jackson.readValue(sourceAsString, Product.class);System.out.println(product);}// 關閉客戶端restHighLevelClient.close(); }7.6、match
@Test void contextLoadsMatch() throws IOException {// 初始化HighLevel客戶端RestHighLevelClient restHighLevelClient = new RestHighLevelClient(RestClient.builder(new HttpHost("127.0.0.1",9200),new HttpHost("127.0.0.1",9300),new HttpHost("127.0.0.1",9400)));SearchRequest searchRequest = new SearchRequest();SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();searchSourceBuilder.query(QueryBuilders.matchQuery("title","新款"));searchRequest.source(searchSourceBuilder);SearchResponse search = restHighLevelClient.search(searchRequest);SearchHits hits = search.getHits();SearchHit[] hits1 = hits.getHits();for (SearchHit documentFields : hits1) {String sourceAsString = documentFields.getSourceAsString();Product product = jackson.readValue(sourceAsString, Product.class);System.out.println(product);}// 關閉客戶端restHighLevelClient.close(); }7.7、range
@Test void contextLoadsRange() throws IOException {// 初始化HighLevel客戶端RestHighLevelClient restHighLevelClient = new RestHighLevelClient(RestClient.builder(new HttpHost("127.0.0.1",9200),new HttpHost("127.0.0.1",9300),new HttpHost("127.0.0.1",9400)));SearchRequest searchRequest = new SearchRequest();SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();searchSourceBuilder.query(QueryBuilders.rangeQuery("price").gt(2000).lt(4000));searchRequest.source(searchSourceBuilder);SearchResponse search = restHighLevelClient.search(searchRequest);SearchHits hits = search.getHits();SearchHit[] hits1 = hits.getHits();for (SearchHit documentFields : hits1) {String sourceAsString = documentFields.getSourceAsString();Product product = jackson.readValue(sourceAsString, Product.class);System.out.println(product);}// 關閉客戶端restHighLevelClient.close(); }7.8、source過濾
默認情況下,索引庫中所有數據都會返回,如果我們想只返回部分字段,可以通過source filter來控制
@Test void contextLoadsSource() throws IOException {// 初始化HighLevel客戶端RestHighLevelClient restHighLevelClient = new RestHighLevelClient(RestClient.builder(new HttpHost("127.0.0.1",9200),new HttpHost("127.0.0.1",9300),new HttpHost("127.0.0.1",9400)));SearchRequest searchRequest = new SearchRequest();SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();searchSourceBuilder.query(QueryBuilders.rangeQuery("price").gt(2000).lt(4000));// 第一個參數想要包含的字段,第二個參數不想要包含的字段searchSourceBuilder.fetchSource(new String[]{"title","price"},null);searchRequest.source(searchSourceBuilder);SearchResponse search = restHighLevelClient.search(searchRequest);SearchHits hits = search.getHits();SearchHit[] hits1 = hits.getHits();for (SearchHit documentFields : hits1) {String sourceAsString = documentFields.getSourceAsString();Product product = jackson.readValue(sourceAsString, Product.class);System.out.println(product);}// 關閉客戶端restHighLevelClient.close(); }7.9、排序
@Test void contextLoadsSort() throws IOException {// 初始化HighLevel客戶端RestHighLevelClient restHighLevelClient = new RestHighLevelClient(RestClient.builder(new HttpHost("127.0.0.1",9200),new HttpHost("127.0.0.1",9300),new HttpHost("127.0.0.1",9400)));SearchRequest searchRequest = new SearchRequest();SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();searchSourceBuilder.query(QueryBuilders.rangeQuery("price").gt(2000).lt(4000));// 降序排序searchSourceBuilder.sort("price", SortOrder.DESC);searchRequest.source(searchSourceBuilder);SearchResponse search = restHighLevelClient.search(searchRequest);SearchHits hits = search.getHits();SearchHit[] hits1 = hits.getHits();for (SearchHit documentFields : hits1) {String sourceAsString = documentFields.getSourceAsString();Product product = jackson.readValue(sourceAsString, Product.class);System.out.println(product);}// 關閉客戶端restHighLevelClient.close(); }7.10、分頁
@Test void contextLoadsSort() throws IOException {// 初始化HighLevel客戶端RestHighLevelClient restHighLevelClient = new RestHighLevelClient(RestClient.builder(new HttpHost("127.0.0.1",9200),new HttpHost("127.0.0.1",9300),new HttpHost("127.0.0.1",9400)));SearchRequest searchRequest = new SearchRequest();SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();searchSourceBuilder.query(QueryBuilders.matchAllQuery());// 降序排序searchSourceBuilder.sort("price", SortOrder.DESC);//searchSourceBuilder.from(0);searchSourceBuilder.size(2);searchRequest.source(searchSourceBuilder);SearchResponse search = restHighLevelClient.search(searchRequest);SearchHits hits = search.getHits();SearchHit[] hits1 = hits.getHits();for (SearchHit documentFields : hits1) {String sourceAsString = documentFields.getSourceAsString();Product product = jackson.readValue(sourceAsString, Product.class);System.out.println(product);}// 關閉客戶端restHighLevelClient.close(); }8、Spring Data Elastic search
Spring Data 的使命是給各種數據訪問提供統一的編程接口,不管是關系型數據庫(如MySQL),還是 非關系數據庫(如Redis),或者類似Elasticsearch這樣的索引數據庫。從而簡化開發人員的代碼,提 高開發效率。
- 支持Spring的基于 @Configuration 的java配置方式,或者XML配置方式
- 提供了用于操作ES的便捷工具類 ElasticsearchTemplate 。包括實現文檔到POJO之間的自動智能映射
- 利用Spring的數據轉換服務實現的功能豐富的對象映射
- 基于注解的元數據映射方式,而且可擴展以支持更多不同的數據格式,可以定義JavaBean:類名、屬性
- 根據持久層接口自動生成對應實現方法,無需人工編寫基本操作代碼(類似mybatis,根據接口自 動得到實現)。當然,也支持人工定制查詢
8.1、創建索引庫
導入依賴
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><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> @Document(indexName = "winkto", type = "product", shards = 3, replicas = 1) public class Product {@Idprivate Long id;@Field(type = FieldType.Text,analyzer = "ik_max_word")private String title;@Field(type = FieldType.Keyword)private String category;@Field(type = FieldType.Keyword)private String brand;@Field(type = FieldType.Double)private Double price;@Field(type = FieldType.Keyword)private String images; } @SpringBootTest class EsDataApplicationTests {@Autowiredprivate ElasticsearchTemplate elasticsearchTemplate;@Testvoid contextLoadsIndex() {elasticsearchTemplate.createIndex(Product.class);} }application.yaml
spring:data:elasticsearch:cluster-name: my-applicationcluster-nodes: 127.0.0.1:9201,127.0.0.1:9301,127.0.0.1:9401
8.2、創建類型映射
@Test void contextLoadsMapping() {elasticsearchTemplate.putMapping(Product.class); }8.3、索引數據CRUD
添加數據(單條)
@Test void contextLoadsInsert() {Product product = new Product(1L, "小米手機7", "手機", "小米", 3299.00, "/13123.jpg");productMapper.save(product); }
添加數據(多條)
根據id查詢
查詢所有
@Test void contextLoadsSelectAll() {Iterable<Product> all = productMapper.findAll();all.forEach(System.out::println); }根據id刪除
@Test void contextLoadsDelete() {productMapper.deleteById(1L); } 創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的Java微服务篇4——Elastic search的全部內容,希望文章能夠幫你解決所遇到的問題。