1. es 使用 restful 風格的 api
備注: es 的 api 格式 基本是這個樣 請求方式 /索引名/文檔名/id?參數 ,但是 還有 很多不是這樣的 請求,比如 _cat api 等等........
2. 查詢 所有索引 get /_cat/indices
3.查看節點健康 get /_cat/health?v
4.?v 的意思 顯示列出項 的title
5.?pretty 結果 json 格式化的方式輸出
6.添加索引 put /test1
7. 添加一條 docment( 如果已經存在 那么久全部覆蓋)
PUT /test1/d1/1 { "age":1, "name":"zs", "bri":"2018-08-08" }
備注1:如果已經存在就全覆蓋修改。
備注2:如果 只需要插入,不修改 着 在后面 加上 /_create (這時候會提示已經存在),post 不能帶_create
8.修改 一條文檔
POST /test1/d1/2 { "age":1, "name":"zs", "bri":"2018-08-08" }
備注: post 雖然叫做修改,但是 在帶有id 的情況下 和 put 幾乎一樣(id 存在就是 全量 修改,不存在就是 新增)。
備注2: 可以 使用 POST /test1/d1 不帶id 的方式 自動生成id,put 不支持不帶id的寫法。
備注3 post 可以 指定_update ,並且 可以帶_create。
備注4:post 可以部分更新 專用名字 partial update
POST /test1/d1/5/_update { "doc":{ "age":2 } }
9.刪除一條文檔 DELETE test1/d1/5
10. 刪除一條索引 DELETE test1
11. 關於 primary shard 和 replica shard 的解釋
primary shard:se 對數據進行切片 ,吧一個索引的 數據 分成多份 ,每一份數據就是一個 primary shard, primary shard 的數量只能在創建索引的時候指定,因為后期 修改 primary shard 數量 會亂 文檔id 計算 文檔所在 shard 的 結果。
replica shard: 副本節點,多個副本節點可以提高數據的安全性,並且可以分擔 primary shard 的查詢 負載。
備注: 修改只能發生在 primary shard ,查詢可以發生在任意 shard 。
12.查詢單條 文檔 get user/student/2
13. 搜索文檔 get user/_search 或者 get user/syudent/_search
備注:查詢可以不指定 type 的類型
14 url 的查詢 get user/_search?-q=name2 ,+q是默認的,-q便是 不存在這樣的數據
備注:沒有指定查詢字段,使用的 一個特俗的 包含全部字段的字段查詢的。
15 指定 字段 url 的查詢 get user/student/_search?q=name:n5
備注:+q=name:n5&q=name:n5
16 url query 的方式很難應 復雜查詢 所以我們一般使用 json 格式的請求體的方式
備注:es restful 風格api 的 get 請求 支持請求體
17 查詢 所有
get /user/student/_search { "query":{ "match_all": {} } }
18 指定字段查詢
get /user/student/_search { "query":{ "match": { "name": "n5" } } }
19 范圍 查詢
get /user/student/_search { "query":{ "range": { "bri": { "gte": 10, "lte": 20 } } } }
20 多條件的 復合 查詢
get /user/student/_search { "query":{ "bool": { "must": [ { "match": { "FIELD": "TEXT" }} ], "should": [ {"match": { "FIELD": "TEXT" }, "match": { "FIELD": "TEXT" } } ], "minimum_should_match": 1 } } }
備注:bool 里面的 都是一些 條件 ,must 必須瞞足,should 只要要滿足 minimum_should_match 個 條件是ture ,filter 只是過濾 不計入評分。
21: 查詢非分頁
get /user/student/_search { "query":{ "match_all": {} }, "from":3, "size":2 }
備注:深分頁問題,效率會很低,勁量避免深分頁。
備注2:深分頁:如果要查詢出 每頁 100 條,的第 100 頁數據數據( 9900 - 10000 ),如果是去5 個節點查詢,那么會在 每個節點查詢出 第 9900- 10000 條數據,然后 匯總到 坐標幾點,然后排序后取出 9900-10000 條,這樣做非常占 資源。
22. scoll 游標查詢,指定 scroll=時間 ,指定保存的分鍾數,第一次發起請求放回的不是數據,而是 _scroll_id ,后面通過 _scroll_id 去請求數據,非常適合大批量查詢。
get /user/student/_search?scroll=1m { "query":{ "match_all": {} }, "size":2 }
GET /_search/scroll { "scroll": "1m", "scroll_id" : "DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAAIuFkRMbVZ0WFdvU1ZHWEJuelFIQk4tdFEAAAAAAAACLBZETG1WdFhXb1NWR1hCbnpRSEJOLXRRAAAAAAAAAi0WRExtVnRYV29TVkdYQm56UUhCTi10UQAAAAAAAAO1FlQwSkJqVng5UVpPUTIwbWw0a0NKV3cAAAAAAAADthZUMEpCalZ4OVFaT1EyMG1sNGtDSld3" }
備注:游標 查詢 是在 es 里面緩存了結果 ,然后一次 一次的去取 所以發起 第一次請求的時候只有 size ,沒有from ,后面的 請求只有 scroll_id 和 scroll 時間
23: 只 顯示指定結果 ( _source )
GET /user/_search { "query": { "match_all": {} }, "_source": ["bri"] }
24: post_filter 和 query 的 區別 ,語法上沒區別,唯一的在於 filter 不評分,所以 filter 比 query 快很多 ,filter 和query 可以共存。
GET /user/_search { "post_filter": { "match_all": {} }, "_source": ["bri"] }
25 聚合函數 球了平均值和 總數量
GET user/student/_search { "query": { "match_all": {} }, "aggs": { "total_count": { "value_count": { "field": "age" } }, "pjz":{ "avg": { "field": "age" } } } }
26:分組
GET user/student/_search { "query": { "match_all": {} }, "aggs": { "fz": { "terms": { "field": "age" } } } }
27 : 遇到 Fielddata is disabled on text fields by default 異常的 解決方案
因為text類型默認沒有正排索引,所以不支持排序 和聚合 ,遇到這種 異常的時候 需要制定 開啟正排索引。
倒排索引用於搜索,正排索引用於排序和聚合。
28:開啟正排索引的方法。
put user/_mapping/student/ { "properties": { "sex": { "type":"text", "fielddata":true } } }
29: 批查詢 api mget
#批量查詢 GET /_mget { "docs":[ { "_index":"user", "_type":"student", "_id":1 }, { "_index":"user", "_type":"student", "_id":2 }, { "_index":"user", "_type":"student", "_id":2 } ] }
備注:mget 如果請求url 里面有 index 和 type 后面 的 請求體里面就可以不寫 index 和type
如:
#批量查詢 GET /user/_mget { "docs":[ { "_type":"student", "_id":1 }, { "_type":"student", "_id":2 }, { "_type":"student", "_id":21111111 } ] }
30 批處理 bulk
bulk的格式:action:index/create/update/delete 后面如果有請求體就跟上請求體
GET _bulk {"create":{"_index":"user","_type":"student","_id":"100"}} { "name": "zhaoer","age": 7, "sex": "nn"} {"update":{"_index":"user","_type":"student","_id":"100"}} {"doc":{ "name": "zhaoer","age": 7, "sex": "nn"}} {"delete":{"_index":"user","_type":"student","_id":"100"}} {"index":{"_index":"user","_type":"student"},"_id":"100"} {"doc":{ "name": "zhaoer","age": 7, "sex": "nn"}}
備注:delete 沒有請求體。
備注2:create 和 update 只有在指定的狀態才能成功 create 創建 ,update 更新。
備注3 ,批處理中的一個 失敗不影響 其他的 執行。
備注4 ,update 需要 doc 包一層
備注5 ,index 有create 和 update 的 功能,並且支持 又或者 沒有 doc 包一層都支持。
31 ,es 的刪除是 是假刪除並且在下一次merge的時候真刪除
32,es的 並發處理 ,使用的樂觀鎖 在 后面加上 version
POST /user/student/1?version=3 { "name":"zyk", "age":0 }
備注:只有version = 當前記錄的version的時候才能修改成功
33.es 可以自動控制 vserion 通過 ,version_type指定 ,
version_type=external 要求 version 大於當前的version ,
version_type=internal 這個是默認值 ,必須等於當前的值
version_type=external_gte 大於等於當前的version
version_type=force 已經廢棄了不能用了,我也不知道以前什么意思,提升, Validation Failed: 1: version type [force] may no longer be used
POST /user/student/1?version_type=external&version=505 { "name":"zyk", "age":0 }
34 ,使用 consistency 指定寫一致性 的等級 (可能廢除了,在6.0 不生效)
consistency=one 只要主節點活着就可以寫
consistency=all 所有主節點和副本節點都活着
consistency=quorun 所有主節點都活着,並且有超過一半的節點(primary shard + replica shard )活着 ,這個是默認值,而且只有在有副本節點的時候才生效
等待 這時候可以指定 timeout 來指定等待時間timeout=30s
35 查詢 索引 的設置
GET /user/_settings
36 查看 索引的 mapping
GET user/_mapping
37動態的 mapping es 或根據第一次存入的數據,動態的決定這個字段的 mapping 類型,並且決定索引行為,后面類型不符合就沒法存入,mapping 里面的 類型不能修改,只能添加新的。
put /test2/t/1 { "age":1, "name":"name", "bri":"2017-09-09", "isDel":true, "amount":0.1 } GET /test2/_mapping
38, 指定 mapping 只能給新的索引指定 ,或者 個新的字段指定
PUT /test2/_mapping/t { "properties": { "age": { "type": "long" }, "amount": { "type": "float" }, "bri": { "type": "date" }, "isDel": { "type": "boolean" }, "name": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } } } }
39,指定 索引的 setting
PUT test3 { "settings": { "index": { "number_of_shards": "3", "number_of_replicas": "1" } } }
PUT test4/_settings { "index": { "number_of_replicas": "4" } }
備注:number_of_shards 不能修改
40:mapping 里面 keyword 的可以指定 text 的子類型
41: 如果 字段類型是 json ,那么這個字段的類型就是 object ,或者說是docment 這時候 mapping 里面是 映射了一個property
42 es 2.X 的 時候string 現在改成 keyword 和 text ,keyword 是存不分詞的 的關鍵數據,text 存大數據,要分詞,
可以個text 類型 指定fields 來指定 一個 不分詞的原文,用於 排序聚合
"name": { "type": "text", "fields": { "keyword": { "type": "keyword" } } }
備注:和2.X的 raw 類似。
43,query phase 指的的查詢的 查詢請求,->坐標節點分發請求到對應 shard ,然后 結果匯總到 坐標節點的過程。
44, fetch phase 指的是 查詢結果的doc id 到各個 shard 取文檔的過程。
45 通過 preference 指定 取那些節點查詢。
preference = _primary,_primart_first,_local,_only_node:xyz,_prefer_node:xyz,_shard:2,3
46 . timeout 指定多少時間之內要返回,到了時間一定會返回,即便沒有查詢完,只返回查到的部分。
47. routing , 默認是通過id 路由的。 可以讓類似的結果在同一個 shard 上。
curl -XPOST 'http://localhost:9200/store/order?routing=user123' -d '
{
"productName": "sample",
"customerID": "user123"
}'
48 searche_type
1、query and fetch
向索引的所有分片(shard)都發出查詢請求,各分片返回的時候把元素文檔(document)和計算后的排名信息一起返回。這種搜索方式是最快的。因為相比下面的幾種搜索方式,這種查詢方法只需要去shard查詢一次。但是各個shard返回的結果的數量之和可能是用戶要求的size的n倍。
2、query then fetch(默認的搜索方式)
如果你搜索時,沒有指定搜索方式,就是使用的這種搜索方式。這種搜索方式,大概分兩個步驟,第一步,先向所有的shard發出請求,各分片只返回排序和排名相關的信息(注意,不包括文檔document),然后按照各分片返回的分數進行重新排序和排名,取前size個文檔。然后進行第二步,去相關的shard取document。這種方式返回的document可能是用戶要求的size的n倍,此處勘誤,這是原博客中的錯誤,經測試 query then fetch 方式返回的數量就是 查詢是 setSize()的數量
3、DFS query and fetch
這種方式比第一種方式多了一個初始化散發(initial scatter)步驟,有這一步,據說可以更精確控制搜索打分和排名。這種方式返回的document與用戶要求的size是相等的。同樣勘誤 DFS query and fetch 返回結果的數量是 分片數*size
4、DFS query then fetch
比第2種方式多了一個初始化散發(initial scatter)步驟。這種方式返回的document與用戶要求的size是相等的。
49 Bouncing Results
搜索同一query,結果ES返回的順序卻不盡相同,這就是請求輪詢到不同分片,而未設置排序條件,相同相關性評分情況下,由於評分采用的算法時TF(term frequency)和IDF(inverst document frequecy) 算出的總分在不同的shard上時不一樣的,那么就造成了默認按照_score的分數排序,導致會出現結果不一致的情況。查詢分析時將所有的請求發送到所有的shard上去。可用設置preference為字符串或者primary shard插敘等來解決該問題。preference還可以指定任意值,探后通過這個值算出查詢的節點
50 type 其實就是一個 隱藏的 field
51 mapping root object 就是指 索引mapping 的json對象
52 給索引取一個名字
put user/_aliases/user_al
或者:
POST /_aliases { "actions": [ { "add": { "index": "user", "alias": "user_a" } }, { "add": { "index": "user", "alias": "user_b" } } ] }
備注: 對個索引可以使用同一個別名
53 查詢 別名
get /user/_alias
54 刪除別名
POST /_aliases { "actions": [ { "remove": { "index": "user", "alias": "user_a" } }, { "remove": { "index": "test", "alias": "user_b" } } ] }
55 自定義 分詞器
PUT /user5 { "settings":{ "analysis": { "char_filter": { "my_char_filter":{ "type":"mapping", "mappings":["&=> and"] } }, "filter": { "my_filter":{ "type":"stop", "stopwords":["the","a"] } }, "analyzer": { "my_analyzer":{ "type":"custom", "char_filter":[ "my_char_filter" ], "filter":["my_filter"], "tokenizer":"standard" } } } } }
解釋:定義了一個 char_filter 名叫 my_char_filter,類型是 mapping 把& 轉成 and
定義了一個 filter 名叫 my_filter ,類型是停用詞,把 the ,a 去掉
定義了一個分析器 名叫 my_analyzer, 類型是自定義,它使用了 char_filter 是 my_char_filter ,它使用的 filter 是 my_filter ,它使用的 分詞器是 標准分詞器。
例子二:
PUT /user9 { "settings":{ "analysis": { "char_filter": { "my_char_filter":{ "type":"mapping", "mappings":["& => and", "pingguo => pingg"] } }, "filter": { "my_filter":{ "type":"stop", "stopwords":["the","a"] } }, "analyzer": { "my_analyzer":{ "type":"custom", "char_filter":[ "my_char_filter" ], "filter":["my_filter"], "tokenizer":"standard" } } } } } GET /user9/_analyze { "analyzer":"my_analyzer", "text":" a d&og is in the house pingguo" }
56 自定義 動態mapping
PUT my_index1 { "mappings": { "_doc":{ "dynamic":"strict", "properties":{ "name":{ "type":"text" }, "user":{ "type":"object", "dynamic":"true" } } } } }
GET my_index1/_doc/1 { "name":"name1", "user":{ "name":"n1", "age":10 }, "age":2 }
mapping的第一層,也就是 properties的 那一層,不允許動態映射,有新的字段就報錯,
user的那一層,允許動態映射,有新的字段就根據 新的第一次的值,指定類型。
dynamic = false 的時候 會存進去,但是我試了一次,不管 1 還是 "1"都可以存進去,但是 也可以查看得到,但是好像搜索不到。
57 document 寫入原理
每次寫請求寫入到 內存 buffer ,當 寫到一定程度的時候,刷新,buffer 寫到 lucene 的 segment,大概1 秒一次。segment 會吧數據寫到 oscache ,然后執行 fsysc 命令吧 歐式chache 寫到disk中。刪除的時候是加刪除,在index segment 中創建一個.del文件,在一定時候index segment 合並的時候,會刪除這個del文件。更新,先執行刪除,然后在執行插入。值得注意的是,沒個一秒 buffer 提交一次,並且產生一個新的 segment,而且,這時候會出發 segment 到 oscache 的提交。數據提交到 os cache 的 以后就可以搜索到了,所以這就是 1 秒 近實時的原因。可以給index指定刷新的時間。 refresh_interval,並且 es 還會寫 tranlog(寫buffer的同時)文件,這個文件可以避免丟失。每次提交會創建一個tranlog 文件,提交完成會刪除原來的 tranlog 文件。在提交以后記錄會寫到新的 tranlog 中。
58. 查看 一段文本是在某個分詞器上是怎么分詞的。
GET /user/_analyze { "analyzer": "standard", "text": " a dog is in the house" }
59 : 給指定 字段指定指定的分詞器
put /user3/_mapping/student { "properties":{ "name":{ "type":"text", "analyzer":"standard" } } }
60: dynamic 策略 三種 ,true (遇到陌生字段就 dynamic mapping ),false(遇到陌生字段就忽略) ,strict(遇到陌生字段就報錯)
61:post /my_index/_optimize?max_num_segments=1
手動使 索引 merge