es入门 和 dsl语法部分讲解
ElasticSearch與Lucene的關系
Lucene可以被認為是迄今為止最先進、性能最好的、功能最全的搜索引擎庫(框架)
但是想要使用Lucene,必須使用Java來作為開發語言并將其直接集成到你的應用中,并且Lucene的配置及使用非常復雜,你需要深入了解檢索的相關知識來理解它是如何工作的。
Lucene缺點:
???1)只能在Java項目中使用,并且要以jar包的方式直接集成項目中.
???2)使用非常復雜-創建索引和搜索索引代碼繁雜
???3)不支持集群環境-索引數據不同步(不支持大型項目) ??
???4)索引數據如果太多就不行,索引庫和應用所在同一個服務器,共同占用硬盤.共用空間少.
上述Lucene框架中的缺點,ES全部都能解決.
ES vs Solr比較
當單純的對已有數據進行搜索時,Solr更快。
當實時建立索引時, Solr會產生io阻塞,查詢性能較差, Elasticsearch具有明顯的優勢。 因為一般互聯網公司都是 實時建立索引 查詢的
大型互聯網公司,實際生產環境測試,將搜索引擎從Solr轉到 Elasticsearch以后的平均查詢速度有了50倍的提升。
總結:
二者安裝都很簡單。
1、Solr 利用 Zookeeper 進行分布式管理,而Elasticsearch 自身帶有分布式協調管理功能。
2、Solr 支持更多格式的數據,比如JSON、XML、CSV,而 Elasticsearch 僅支持json文件格式。
3、Solr 在傳統的搜索應用中表現好于 Elasticsearch,但在處理實時搜索應用時效率明顯低于 Elasticsearch。
4、Solr 是傳統搜索應用的有力解決方案,但 Elasticsearch更適用于新興的實時搜索應用。
1.4.2 ES vs 關系型數據庫
為什么海量數據es比mysql快
因為?不像mysql 一條數據就增長一行
常用單詞(漢字)就那么多, 那么就不會無限增長
2. ?Lucene全文檢索框架
2.1 ?什么是全文檢索
全文檢索是指:
- 通過一個程序掃描文本中的每一個單詞,針對單詞建立索引,并保存該單詞在文本中的位置、以及出現的次數
- 用戶查詢時,通過之前建立好的索引來查詢,將索引中單詞對應的文本位置、出現的次數返回給用戶,因為有了具體文本的位置,所以就可以將具體內容讀取出來了
1、倒排索引:
索引就類似于目錄,平時我們使用的都是索引,都是通過主鍵定位到某條數據,那么倒排索引呢,剛好相反,數據對應到主鍵.這里以一個博客文章的內容為例:
1.索引
| 文章ID | 文章標題 | 文章內容 |
| 1 | 淺析JAVA設計模式 | JAVA設計模式是每一個JAVA程序員都應該掌握的進階知識 |
| 2 | JAVA多線程設計模式 | JAVA多線程與設計模式結合 |
2.分詞原理之倒排索引
假如,我們有一個站內搜索的功能,通過某個關鍵詞來搜索相關的文章,那么這個關鍵詞可能出現在標題中,也可能出現在文章內容中,那我們將會在創建或修改文章的時候,建立一個關鍵詞與文章的對應關系表,這種,我們可以稱之為倒排索引,因此倒排索引,也可稱之為反向索引.如:
| 關鍵詞 | 文章ID |
| JAVA | 1 |
| 設計模式 | 1,2 |
| 多線程 | 2 |
注:這里涉及中文分詞的問題
2、安裝出現異常
1)盡量不要復制pdf中的文字,可以復制有道云筆記中的文字
2、ES比較耗內存,建議虛擬機4G或以上內存 jvm1g以上的內存分配
英文分詞用空格區分? ?原始數據在索引庫里面還是存在的
中文分詞就麻煩
倒排索引 就是根據關鍵詞來搜索文章id
正排索引:根據id(索引) 找詞條(記錄信息)
Elasticsearch中的核心概念
3.1 ?索引 index
一個索引就是一個擁有幾分相似特征的文檔的集合。比如說,可以有一個客戶數據的索引,另一個產品目錄的索引,還有一個訂單數據的索引
一個索引由一個名字來標識(必須全部是小寫字母的),并且當我們要對對應于這個索引中的文檔進行索引、搜索、更新和刪除的時候,都要使用到這個名字
3.2 ?映射 mapping
?ElasticSearch中的映射(Mapping)用來定義一個文檔
mapping是處理數據的方式和規則方面做一些限制,如某個字段的數據類型、默認值、分詞器、是否被索引等等,這些都是映射里面可以設置的
3.3 ?字段Field
相當于是數據表的字段|列
3.4 ?字段類型 Type
每一個字段都應該有一個對應的類型,例如:Text、Keyword、Byte等
3.5 ?文檔 document
一個文檔是一個可被索引的基礎信息單元,類似一條記錄。文檔以JSON(Javascript Object Notation)格式來表示;
3.6 ?集群 cluster
一個集群就是由一個或多個節點組織在一起,它們共同持有整個的數據,并一起提供索引和搜索功能
3.7 ?節點 node
一個節點是集群中的一個服務器,作為集群的一部分,它存儲數據,參與集群的索引和搜索功能
?一個節點可以通過配置集群名稱的方式來加入一個指定的集群。默認情況下,每個節點都會被安排加入到一個叫做“elasticsearch”的集群中
這意味著,如果在網絡中啟動了若干個節點,并假定它們能夠相互發現彼此,它們將會自動地形成并加入到一個叫做“elasticsearch”的集群中
?在一個集群里,可以擁有任意多個節點。而且,如果當前網絡中沒有運行任何Elasticsearch節點,這時啟動一個節點,會默認創建并加入一個叫做“elasticsearch”的集群。
3.8 ?分片和副本 shards&replicas
3.8.1 ?分片
- 一個索引可以存儲超出單個結點硬件限制的大量數據。比如,一個具有10億文檔的索引占據1TB的磁盤空間,而任一節點都沒有這樣大的磁盤空間;或者單個節點處理搜索請求,響應太慢
- 為了解決這個問題,Elasticsearch提供了將索引劃分成多份的能力,這些份就叫做分片
- 當創建一個索引的時候,可以指定你想要的分片的數量
- 每個分片本身也是一個功能完善并且獨立的“索引”,這個“索引”可以被放置到集群中的任何節點上
- 分片很重要,主要有兩方面的原因
? 允許水平分割/擴展你的內容容量
允許在分片之上進行分布式的、并行的操作,進而提高性能/吞吐量
- 至于一個分片怎樣分布,它的文檔怎樣聚合回搜索請求,是完全由Elasticsearch管理的,對于作為用戶來說,這些都是透明的
3.8.2 ?副本
- 在一個網絡/云的環境里,失敗隨時都可能發生,在某個分片/節點不知怎么的就處于離線狀態,或者由于任何原因消失了,這種情況下,有一個故障轉移機制是非常有用并且是強烈推薦的。為此目的,Elasticsearch允許你創建分片的一份或多份拷貝,這些拷貝叫做副本分片,或者直接叫副本
- 副本之所以重要,有兩個主要原因
1) ?在分片/節點失敗的情況下,提供了高可用性。
注意到復制分片從不與原/主要(original/primary)分片置于同一節點上是非常重要的 (錯峰 和redis cluster一樣)
2) 擴展搜索量/吞吐量,因為搜索可以在所有的副本上并行運行
每個索引可以被分成多個分片。一個索引有0個或者多個副本
一旦設置了副本,每個索引就有了主分片和副本分片,分片和副本的數量可以在索引
創建的時候指定在索引創建之后,可以在任何時候動態地改變副本的數量,但是不能改變分片的數量
5 客戶端Kibana安裝
5.1客戶端可以分為圖形界面客戶端,和代碼客戶端.
5.2 ES主流客戶端Kibana,開放9200端口與圖形界面客戶端交互
安裝IK分詞器
IK Analyzer 是一個開源的,基于 java 語言開發的輕量級的中文分詞工具包。從 2006年 12 月推出 1.0 版開始, IKAnalyzer 已經推出了 4 個大版本。最初,它是以開源項目Luence 為應用主體的,結合詞典分詞和文法分析算法的中文分詞組件。從 3.0 版本開始,IK 發展為面向 Java 的公用分詞組件,獨立 Lucene 項目,同時提供了對 Lucene 的默認優化實現。在 2012 版本中,IK 實現了簡單的分詞歧義排除算法,標志著 IK 分詞器從單純的詞典分詞向模擬語義分詞衍化。
指定IK分詞器作為默認分詞器
ES的默認分詞設置是standard,這個在中文分詞時就比較尷尬了,會單字拆分,比如我搜索關鍵詞“清華大學”,這時候會按“清”,“華”,“大”,“學”去分詞,然后搜出來的都是些“清清的河水”,“中華兒女”,“地大物博”,“學而不思則罔”之類的莫名其妙的結果,這里我們就想把這個分詞方式修改一下,于是呢,就想到了ik分詞器,有兩種ik_smart和ik_max_word。
ik_smart會將“清華大學”整個分為一個詞,而ik_max_word會將“清華大學”分為“清華大學”,“清華”和“大學”,按需選其中之一就可以了。
修改默認分詞方法(這里修改school_index索引的默認分詞為:ik_max_word):
PUT /school_index { "settings" : { "index" : { "analysis.analyzer.default.type": "ik_max_word" } } }8.ES數據管理
8.1 ES數據管理概述
ES是面向文檔(document oriented)的,這意味著它可以存儲整個對象或文檔(document)。
然而它不僅僅是存儲,還會索引(index)每個文檔的內容使之可以被搜索。
在ES中,你可以對文檔(而非成行成列的數據)進行索引、搜索、排序、過濾。
ES使用JSON作為文檔序列化格式。
JSON現在已經被大多語言所支持,而且已經成為NoSQL領域的標準格式。
ES存儲的一個員工文檔的格式示例:
{ "email": "584614151@qq.com", "name": "張三", "age": 30, "interests": [ "籃球", "健身" ]}8.2 基本操作
1) 創建索引
格式: PUT /索引名稱
舉例: PUT /es_db2) 查詢索引
格式: GET /索引名稱
舉例: GET /es_db3) 刪除索引
格式: DELETE /索引名稱
舉例: DELETE /es_db4) 添加文檔
格式: PUT /索引名稱/類型/id
舉例: PUT /es_db/_doc/1 { "name": "張三", "sex": 1, "age": 25, "address": "廣州天河公園", "remark": "java developer" }PUT /es_db/_doc/2 { "name": "李四", "sex": 1, "age": 28, "address": "廣州荔灣大廈", "remark": "java assistant" }PUT /es_db/_doc/3 { "name": "rod", "sex": 0, "age": 26, "address": "廣州白云山公園", "remark": "php developer" }PUT /es_db/_doc/4 { "name": "admin", "sex": 0, "age": 22, "address": "長沙橘子洲頭", "remark": "python assistant" }PUT /es_db/_doc/5 { "name": "小明", "sex": 0, "age": 19, "address": "長沙岳麓山", "remark": "java architect assistant" }5) 修改文檔
格式: PUT /索引名稱/類型/id 舉例: PUT /es_db/_doc/1 { "name": "白起老師", "sex": 1, "age": 25, "address": "張家界森林公園", "remark": "php developer assistant" }注意:POST和PUT都能起到創建/更新的作用
1、需要注意的是==PUT==需要對一個具體的資源進行操作也就是要確定id才能進行==更新/創建,而==POST==是可以針對整個資源集合進行操作的,如果不寫id就由ES生成一個唯一id進行==創建==新文檔,如果填了id那就針對這個id的文檔進行創建/更新
2、PUT只會將json數據都進行替換, POST只會更新相同字段的值
3、PUT與DELETE都是冪等性操作, 即不論操作多少次, 結果都一樣
6) 查詢文檔
格式: GET /索引名稱/類型/id 舉例: GET /es_db/_doc/17) 刪除文檔
格式: DELETE /索引名稱/類型/id 舉例: DELETE /es_db/_doc/19.Restful認識
Restful是一種面向資源的架構風格,可以簡單理解為:使用URL定位資源,用HTTP動詞(GET,POST,DELETE,PUT)描述操作。 基于Restful API?ES和所有客戶端的交互都是使用JSON格式的數據.
其他所有程序語言都可以使用RESTful API,通過9200端口的與ES進行通信
GET查詢
PUT添加
POST修改
DELE刪除
用戶做crud
Get http://localhost:8080/employee/1???Get http://localhost:8080/employeesput http://localhost:8080/employee {} delete http://localhost:8080/employee/1Post http://localhost:8080/employee/1 { }使用Restful的好處:
透明性,暴露資源存在。
充分利用 HTTP 協議本身語義,不同請求方式進行不同的操作
10.查詢操作
10.1 查詢當前類型中的所有文檔 _search
格式: GET /索引名稱/類型/_search 舉例: GET /es_db/_doc/_search SQL: ?select * from student10.2 條件查詢, 如要查詢age等于28歲的 _search?q=*:***
格式: GET /索引名稱/類型/_search?q=*:*** 舉例: GET /es_db/_doc/_search?q=age:28 SQL: ?select * from student where age = 2810.3 范圍查詢, 如要查詢age在25至26歲之間的 _search?q=***[** TO **] ?注意: TO 必須為大寫
格式: GET /索引名稱/類型/_search?q=***[25 TO 26] 舉例: GET /es_db/_doc/_search?q=age[25 TO 26] SQL: ?select * from student where age between 25 and 2610.4 根據多個ID進行批量查詢 _mget
格式: GET /索引名稱/類型/_mget 舉例: GET /es_db/_doc/_mget? {"ids":["1","2"] ?} SQL: ?select * from student where id in (1,2)10.5 查詢年齡小于等于28歲的 :
格式: GET /索引名稱/類型/_search?q=age:<=** 舉例: GET /es_db/_doc/_search?q=age:<=28 SQL: ?select * from student where age <= 2810.6 查詢年齡大于28前的 :>
格式: GET /索引名稱/類型/_search?q=age:>** 舉例: GET /es_db/_doc/_search?q=age:>28 SQL: ?select * from student where age > 2810.7 分頁查詢 from=*&size=*
格式: GET /索引名稱/類型/_search?q=age[25 TO 26]&from=0&size=1 舉例: GET /es_db/_doc/_search?q=age[25 TO 26]&from=0&size=1 SQL: ?select * from student where age between 25 and 26 limit 0, 110.8 對查詢結果只輸出某些字段 _source=字段,字段
格式: GET /索引名稱/類型/_search?_source=字段,字段 舉例: GET /es_db/_doc/_search?_source=name,age SQL: ?select name,age from student10.9 對查詢結果排序 sort=字段:desc/asc
格式: GET /索引名稱/類型/_search?sort=字段 desc
格式: GET /索引名稱/類型/_search?sort=字段 desc 舉例: GET /es_db/_doc/_search?sort=age:desc SQL: ?select * from student order by age desc7.x后的es type(類似數據庫的表)都是統一的 _doc 這樣的? 8 版本的就直接沒了
dsl 是es查詢的核心 復雜查詢
DSL語言高級查詢
1.Query DSL概述
Domain Specific Language
領域專用語言
Elasticsearch provides a ful1 Query DSL based on JSON to define queries
Elasticsearch提供了基于JSON的DSL來定義查詢。
DSL由葉子查詢子句和復合查詢子句兩種子句組成。
2.無查詢條件
無查詢條件是查詢所有,默認是查詢所有的,或者使用match_all表示所有
GET /es_db/_doc/_search { "query":{ "match_all":{} } }把es所有索引庫的信息返回回去 了解一下就行 一般不怎么用
3.有查詢條件
3.1 葉子條件查詢(單字段查詢條件)
3.1.1 模糊匹配
模糊匹配主要是針對文本類型的字段,文本類型的字段會對內容進行分詞,對查詢時,也會對搜索條件進行分詞,然后通過倒排索引查找到匹配的數據,模糊匹配主要通過match等參數來實現
- match : 通過match關鍵詞模糊匹配條件內容
- prefix : 前綴匹配
- regexp : 通過正則表達式來匹配數據
match的復雜用法
match條件還支持以下參數:
- query : 指定匹配的值
- operator : 匹配條件類型
-
- and : 條件分詞后都要匹配
- or : 條件分詞后有一個匹配即可(默認)
- minmum_should_match : 指定最小匹配的數量
3.1.2 精確匹配
- term : 單個條件相等
- terms : 單個字段屬于某個值數組內的值
- range : 字段屬于某個范圍內的值
- exists : 某個字段的值是否存在
- ids : 通過ID批量查詢
3.2 組合條件查詢(多條件查詢)
組合條件查詢是將葉子條件查詢語句進行組合而形成的一個完整的查詢條件
- bool : 各條件之間有and,or或not的關系
-
- must : 各個條件都必須滿足,即各條件是and的關系
- should : 各個條件有一個滿足即可,即各條件是or的關系
- must_not : 不滿足所有條件,即各條件是not的關系
- filter : 不計算相關度評分,它不計算_score即相關度評分,效率更高
- constant_score : 不計算相關度評分
must/filter/shoud/must_not?等的子條件是通過?term/terms/range/ids/exists/match?等葉子條件為參數的
注:以上參數,當只有一個搜索條件時,must等對應的是一個對象,當是多個條件時,對應的是一個數組
3.3 連接查詢(多文檔合并查詢)
- 父子文檔查詢:parent/child
- 嵌套文檔查詢: nested
3.4 DSL查詢語言中存在兩種:查詢DSL(query DSL)和過濾DSL(filter DSL)
它們兩個的區別如下圖:
query DSL
在查詢上下文中,查詢會回答這個問題——“這個文檔匹不匹配這個查詢,它的相關度高么?”
如何驗證匹配很好理解,如何計算相關度呢?ES中索引的數據都會存儲一個_score分值,分值越高就代表越匹配。(就是平時搜索排在前面的)另外關于某個搜索的分值計算還是很復雜的,因此也需要一定的時間。
filter DSL
在過濾器上下文中,查詢會回答這個問題——“這個文檔匹不匹配?”
答案很簡單,是或者不是。它不會去計算任何分值,也不會關心返回的排序問題,因此效率會高一點。
過濾上下文 是在使用filter參數時候的執行環境,比如在bool查詢中使用must_not或者filter
另外,經常使用過濾器,ES會自動的緩存過濾器的內容,這對于查詢來說,會提高很多性能。
一些過濾的情況:
3.5 Query方式查詢:案例
- 根據名稱精確查詢姓名 term, term查詢不會對字段進行分詞查詢,會采用精確匹配
注意: 采用term精確查詢, 查詢字段映射類型屬于為keyword.??單個條件相等? 代表下面的信息不需要分詞了
舉例:
POST /es_db/_doc/_search { "query": { "term": { "name": "admin" } } } SQL: select * from student where name = 'admin'term查詢keyword字段。
?term不會分詞。而keyword字段也不分詞。需要完全匹配才可。
term查詢text字段。
因為text字段會分詞,而term不分詞,所以term查詢的條件必須是text字段分詞后的某一個。
- 根據備注信息模糊查詢 match, match會根據該字段的分詞器,進行分詞查詢
舉例:
POST /es_db/_doc/_search { "from": 0, "size": 2, "query": { "match": { "address": "廣州" } } } SQL: select * from user where address like '%廣州%' limit 0, 2- 多字段模糊匹配查詢與精準查詢 multi_match
- 未指定字段條件查詢 query_string , 含 AND 與 OR 條件
- 就是指所有字段 有廣州或者長沙的
- 指定字段條件查詢 query_string , 含 AND 與 OR 條件
- POST /es_db/_doc/_search { "query":{ "query_string":{ "query":"admin OR 長沙", "fields":["name","address"] } } }
- 范圍查詢
注:json請求字符串中部分字段的含義
range:范圍關鍵字
gte 大于等于
lte ?小于等于
gt 大于
lt 小于
now 當前時間
POST /es_db/_doc/_search { "query" : { "range" : { "age" : { "gte":25, "lte":28 } } } } SQL: select * from user where age between 25 and 28- 分頁、輸出字段、排序綜合查詢
- POST /es_db/_doc/_search { "query" : { "range" : { "age" : { "gte":25, "lte":28 } } }, "from": 0, "size": 2, "_source": ["name", "age", "book"], "sort": {"age":"desc"} }
3.6 Filter過濾器方式查詢,它的查詢不會計算相關性分值,也不會對結果進行排序, 因此效率會高一點,查詢的結果可以被緩存。
Filter Context 對數據進行過濾
POST /es_db/_doc/_search { "query" : { "bool" : { "filter" : { "term":{ "age":25 } } } } }總結:
1. match
match:模糊匹配,需要指定字段名,但是輸入會進行分詞,比如"hello world"會進行拆分為hello和world,然后匹配,如果字段中包含hello或者world,或者都包含的結果都會被查詢出來,也就是說match是一個部分匹配的模糊查詢。查詢條件相對來說比較寬松。
?
2. term
term: 這種查詢和match在有些時候是等價的,比如我們查詢單個的詞hello,那么會和match查詢結果一樣,但是如果查詢"hello world",結果就相差很大,因為這個輸入不會進行分詞,就是說查詢的時候,是查詢字段分詞結果中是否有"hello world"的字樣,而不是查詢字段中包含"hello world"的字樣。當保存數據"hello world"時,elasticsearch會對字段內容進行分詞,"hello world"會被分成hello和world,不存在"hello world",因此這里的查詢結果會為空。這也是term查詢和match的區別。
?? 雖然books中有name="java in action"的book,但是term查詢還是查詢不出來結果。只有使用單個詞做索引才能查詢出結果:
?
3. match_phase???也就是短語查詢
match_phase:會對輸入做分詞,但是需要結果中也包含所有的分詞,而且順序要求一樣。以"hello world"為例,要求結果中必須包含hello和world,而且還要求他們是連著的,順序也是固定的,hello that world不滿足,world hello也不滿足條件。
增加分詞:
將查詢分詞順序打亂,就查詢不出結果了:
?
4. query_string
query_string:和match類似,但是match需要指定字段名,query_string是在所有字段中搜索,范圍更廣泛。
?
match查詢keyword字段
match會被分詞,而keyword不會被分詞,match的需要跟keyword的完全匹配可以。
match查詢text字段
match分詞,text也分詞,只要match的分詞結果和text的分詞結果有相同的就匹配。
文檔映射
1.ES中映射可以分為動態映射和靜態映射
動態映射:?
在關系數據庫中,需要事先創建數據庫,然后在該數據庫下創建數據表,并創建表字段、類型、長度、主鍵等,最后才能基于表插入數據。而Elasticsearch中不需要定義Mapping映射(即關系型數據庫的表、字段等),在文檔寫入Elasticsearch時,會根據文檔字段自動識別類型,這種機制稱之為動態映射。
動態映射規則如下:
靜態映射:
靜態映射是在Elasticsearch中也可以事先定義好映射,包含文檔的各字段類型、分詞器等,這種方式稱之為靜態映射。
2 動態映射
2.1 刪除原創建的索引
DELETE /es_db2.2 創建索引
PUT /es_db2.3 創建文檔(ES根據數據類型, 會自動創建映射)
PUT /es_db/_doc/1 { "name": "Jack", "sex": 1, "age": 25, "book": "java入門至精通", "address": "廣州小蠻腰" }設置文檔映射
PUT /es_db { "mappings":{ "properties":{ "name":{"type":"keyword","index":true,"store":true}, "sex":{"type":"integer","index":true,"store":true}, "age":{"type":"integer","index":true,"store":true}, "book":{"type":"text","index":true,"store":true}, "address":{"type":"text","index":true,"store":true} } } }四.核心類型(Core datatype)
字符串:string,string類型包含 text 和 keyword。
text:該類型被用來索引長文本,在創建索引前會將這些文本進行分詞,轉化為詞的組合,建立索引;允許es來檢索這些詞,text類型不能用來排序和聚合。
keyword:該類型不能分詞,可以被用來檢索過濾、排序和聚合,keyword類型不可用text進行分詞模糊檢索。
數值型:long、integer、short、byte、double、float
日期型:date
布爾型:boolean
五.keyword 與 text 映射類型的區別
將 book 字段設置為 keyword 映射 (只能精準查詢, 不能分詞查詢,能聚合、排序)
POST /es_db/_doc/_search { "query": { "term": { "book": "elasticSearch入門至精通" } } }將 book 字段設置為 text 映射能模糊查詢, 能分詞查詢,不能聚合、排序)
POST /es_db/_doc/_search { "query": { "match": { "book": "elasticSearch入門至精通" } } }六.創建靜態映射時指定text類型的ik分詞器
1.設置ik分詞器的文檔映射
先刪除之前的es_db
再創建新的es_db
定義ik_smart的映射
PUT /es_db { "mappings":{ "properties":{ "name":{"type":"keyword","index":true,"store":true}, "sex":{"type":"integer","index":true,"store":true}, "age":{"type":"integer","index":true,"store":true}, "book":{"type":"text","index":true,"store":true,"analyzer":"ik_smart","search_analyzer":"ik_smart"}, "address":{"type":"text","index":true,"store":true} } } }2.分詞查詢
POST /es_db/_doc/_search { "query": { "match": {"address": "廣"} } } POST /es_db/_doc/_search { "query": { "match": {"address": "廣州"} } }七.對已存在的mapping映射進行修改
具體方法
1)如果要推倒現有的映射, 你得重新建立一個靜態索引
2)然后把之前索引里的數據導入到新的索引里
3)刪除原創建的索引
4)為新索引起個別名, 為原索引名
POST _reindex { "source": { "index": "db_index" }, "dest": { "index": "db_index_2" } }DELETE /db_indexPUT /db_index_2/_alias/db_index注意: 通過這幾個步驟就實現了索引的平滑過渡,并且是零停機
?
八.Elasticsearch樂觀并發控制
在數據庫領域中,有兩種方法來確保并發更新,不會丟失數據:
1、悲觀并發控制
這種方法被關系型數據庫廣泛使用,它假定有變更沖突可能發生,因此阻塞訪問資源以防止沖突。 一個典型的例子是讀取一行數據之前先將其鎖住,確保只有放置鎖的線程能夠對這行數據進行修改。
2、樂觀并發控制
Elasticsearch 中使用的這種方法假定沖突是不可能發生的,并且不會阻塞正在嘗試的操作。 然而,如果源數據在讀寫當中被修改,更新將會失敗。應用程序接下來將決定該如何解決沖突。 例如,可以重試更新、使用新的數據、或者將相關情況報告給用戶。
3、再以創建一個文檔為例 ES老版本
PUT /db_index/_doc/1 { "name": "Jack", "sex": 1, "age": 25, "book": "Spring Boot 入門到精通", "remark": "hello world" }4、實現_version樂觀鎖更新文檔
PUT /db_index/_doc/1?version=1 { "name": "Jack", "sex": 1, "age": 25, "book": "Spring Boot 入門到精通", "remark": "hello world" }5、ES新版本(7.x)不使用version進行并發版本控制 if_seq_no=版本值&if_primary_term=文檔位置
_seq_no:文檔版本號,作用同_version
_primary_term:文檔所在位置
POST /es_sc/_searchDELETE /es_scPOST /es_sc/_doc/1 { "id": 1, "name": "圖靈學院", "desc": "圖靈學院白起老師", "create_date": "2021-02-24" }POST /es_sc/_update/1 { "doc": { "name": "圖靈教育666" } }POST /es_sc/_update/1/?if_seq_no=1&if_primary_term=1 { "doc": { "name": "圖靈學院1" } }POST /es_sc/_update/1/?if_seq_no=1&if_primary_term=1 { "doc": { "name": "圖靈學院2" } }if_seq_no 和 if_primary_term意義
if_seq_no 和 if_primary_term 是用來并發控制,他們和version不同,version屬于當個文檔,而seq_no屬于整個index。
_primary_term表示文檔所在主分片的編號
_primary_term:_primary_term也和_seq_no一樣都是整數,每當Primary Shard發生重新分配時,比如重啟,Primary選舉等,_primary_term會遞增1。
_primary_term主要是用來恢復數據時處理當多個文檔的_seq_no一樣時的沖突,比如當一個shard宕機了,raplica需要用到最新的數據,就會根據_primary_term和_seq_no這兩個值來拿到最新的document
ES集群環境搭建??
不同節點 集群名稱相同 節點名稱不同 ip不同
注意:搭建es集群,啟動三個es節點,訪問elasticsearch-head時只顯示一個master
解決方案:進到節點2、3的/elasticsearch-7.6.1/data/目錄下刪除nodes文件,之后重啟節點2、3的es進程即可
下圖打上星號的是主節點
集群 主分片出問題? 備份分片? 還是有數據的 不會丟失
Elasticsearch-head插件
由于es服務啟動之后,訪問界面比較丑陋,為了更好的查看索引庫當中的信息,我們可以通過安裝elasticsearch-head這個插件來實現,這個插件可以更方便快捷的看到es的管理界面
elasticsearch-head這個插件是es提供的一個用于圖形化界面查看的一個插件工具,可以安裝上這個插件之后,通過這個插件來實現我們通過瀏覽器查看es當中的數據
安裝elasticsearch-head這個插件這里提供兩種方式進行安裝,第一種方式就是自己下載源碼包進行編譯,耗時比較長,網絡較差的情況下,基本上不可能安裝成功。
第二種方式就是直接使用我已經編譯好的安裝包,進行修改配置即可
要安裝elasticsearch-head插件,需要先安裝Node.js
總結
以上是生活随笔為你收集整理的es入门 和 dsl语法部分讲解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Unity报错但VS(代码编辑器)不报错
- 下一篇: c语言---15 循环语句do whil