1.Index API: 創建並建立索引
PUT twitter/tweet/1 { "user" : "kimchy", "post_date" : "2009-11-15T14:12:12", "message" : "trying out Elasticsearch" }
官方文檔參考:Index API。
2.Get API: 獲取文檔
curl -XGET 'http://localhost:9200/twitter/tweet/1'
官方文檔參考:Get API。
3.DELETE API: 刪除文檔
$ curl -XDELETE 'http://localhost:9200/twitter/tweet/1'
官方文檔參考:Delete API。
4.UPDATE API: 更新文檔
PUT test/type1/1{ "counter" : 1, "tags" : ["red"]}
官方文檔參考:Update API。
5.Multi Get API: 一次批量獲取文檔
PUT 'localhost:9200/_mget { "docs" :
[ {"_index" : "test", "_type" : "type", "_id" : "1" }, { "_index" : "test", "_type" : "type", "_id" : "2" } ] }
官方文檔參考:Multi Get API。
6.Bulk API: 批量操作,增刪改查
1.本地文件批量操作
e$ curl -s -XPOST localhost:9200/blog/user/_bulk --data-binary @requests requests文件內容如下 {"index":{"_id":"25"}} {"name":"黎明","id":25} {"index":{"_id":"26"}} {"name":"小明","id":26} {"index":{"_id":"26"}} {"name":"雄安","id":27} {"index":{"_id":"28"}} {"name":"笑話","id":28}
2.resp 方法
curl -H "Content-Type: application/json" -XPOST 'http://47.52.199.51:9200/book/english/_bulk' -d' {"index":{"_id":"17"}} {"name":"cddd","id":17} {"index":{"_id":"18"}} {"name":"cddd","id":18} {"index":{"_id":"19"}} {"name":"cddd","id":19} {"index":{"_id":"20"}} {"name":"cddd","id":20} '
官方文檔參考:Bulk API。
7.DELETE By Query API: 查詢刪除
POST /book/_delete_by_query { "query":{ "match":{ "name": "yangxioa" } } }
7.1.刪除所有
POST /book/_delete_by_query { "query":{ "match_all":{} } }
7.2.支持路由查詢(routing=XXX,匹配分片數)
POST twitter/_delete_by_query?routing=1 { "query": { "range" : { "age" : { "gte" : 10 } } } }
{ "took" : 147, // 整個操作從開始到結束的毫秒數 "timed_out": false, // true如果在通過查詢執行刪除期間執行的任何請求超時 ,則將此標志設置為。 "total": 119, // 已成功處理的文檔數。 "deleted": 119, // 已成功刪除的文檔數。 "batches": 1, // 通過查詢刪除拉回的滾動響應數。 "version_conflicts": 0, // 按查詢刪除的版本沖突數。 "noops": 0, // 對於按查詢刪除,此字段始終等於零。它只存在,以便通過查詢刪除,按查詢更新和reindex API返回具有相同結構的響應。 "retries": { // 通過查詢刪除嘗試的重試次數。bulk是重試的批量操作search的數量,是重試的搜索操作的數量。 "bulk": 0, "search": 0 }, "throttled_millis": 0, // 請求睡眠符合的毫秒數requests_per_second。 "requests_per_second": -1.0, // 在通過查詢刪除期間有效執行的每秒請求數。 "throttled_until_millis": 0, //在按查詢響應刪除時,此字段應始終等於零。它只在使用Task API時有意義,它指示下一次(自紀元以來的毫秒數),為了符合,將再次執行受限制的請求 "failures" : [ ] //如果在此過程中存在任何不可恢復的錯誤,則會出現故障數組。如果這是非空的,那么請求因為那些失敗而中止。逐個查詢是使用批處理實現的, 任何故障都會導致整個進程中止,但當前批處理中的所有故障都會被收集到數組中。您可以使用該conflicts選項來防止reindex在版本沖突中中止。 }
官方文檔參考:Delete By Query API。
8.update更新api
8.1.腳本更新
POST test/_doc/1/_update { "script" : { "source": "ctx._source.counter += params.count", "lang": "painless",// ES語言類型 "params" : { "count" : 4 } } }
8.2.新增字段
POST test/_doc/1/_update { "script" : "ctx._source.new_field = 'value_of_new_field'" }
8.3.刪除字段
POST test/_doc/1/_update { "script" : "ctx._source.remove('new_field')" }
8.4.存在就更新
POST test/_doc/1/_update { "script" : { "source": "if (ctx._source.tags.contains(params.tag)) { ctx.op = 'delete' } else { ctx.op = 'none' }", "lang": "painless", "params" : { "tag" : "green" } } }
8.5.更新部分字段
POST test/_doc/1/_update { "doc" : { "name" : "new_name" } }
8.6.upsert:存在就更新,不存在插入
POST test/_doc/1/_update { "script" : { "source": "ctx._source.counter += params.count", "lang": "painless", "params" : { "count" : 4 } }, "upsert" : { "counter" : 1 } }
官方文檔參考:Update 腳本更新API
9.UPDATE BY QUERY API:查詢更新
9.1.更新,重新索引
POST twitter/_update_by_query?conflicts=proceed
{ "took" : 147, "timed_out": false, "updated": 120, "deleted": 0, "batches": 1, "version_conflicts": 0, "noops": 0, "retries": { "bulk": 0, "search": 0 }, "throttled_millis": 0, "requests_per_second": -1.0, "throttled_until_millis": 0, "total": 120, "failures" : [ ] }
ES內部自帶實現樂觀鎖控制,先查詢出要更新的記錄的版本號,更新時匹配版本號時候一致。
所有更新和查詢失敗都會導致_update_by_query
中止並failures
在響應中返回。已執行的更新仍然存在。換句話說,該過程不會回滾,只會中止。當第一個失敗導致中止時,失敗的批量請求返回的所有失敗都將在failures
元素中返回; 因此,可能存在相當多的失敗實體。
如果您只想計算版本沖突,不要導致_update_by_query
中止,您可以conflicts=proceed
在URL或"conflicts": "proceed",改配置當第一個沖突時會會繼續執行,
version_conflicts沖突數量。
9.2.查詢更新
POST twitter/_update_by_query?conflicts=proceed { "query": { "term": { "user": "kimchy" } } }
9.3.查詢腳本更新
POST twitter/_update_by_query { "script": { "source": "ctx._source.likes++", "lang": "painless" }, "query": { "term": { "user": "kimchy" } } }
也可以同時在多個索引和多個類型上完成這一切,就像搜索API一樣:
POST twitter,blog / _doc,post / _update_by_query
routing
則路由將復制到滾動查詢,將進程限制為與該路由值匹配的分片:
POST twitter/_update_by_query?routing=1
默認情況下,_update_by_query
使用1000的滾動批次。可以使用scroll_size
URL參數更改批量大小:
POST twitter/_update_by_query?scroll_size=100
9.4.使用TASK API獲取所有正在運行的逐個查詢請求的狀態
GET _tasks?detailed=true&actions=*byquery
結果:
{ "nodes" : { "r1A2WoRbTwKZ516z6NEs5A" : { "name" : "r1A2WoR", "transport_address" : "127.0.0.1:9300", "host" : "127.0.0.1", "ip" : "127.0.0.1:9300", "attributes" : { "testattr" : "test", "portsfile" : "true" }, "tasks" : { "r1A2WoRbTwKZ516z6NEs5A:36619" : { "node" : "r1A2WoRbTwKZ516z6NEs5A", "id" : 36619, "type" : "transport", "action" : "indices:data/write/update/byquery", "status" : { "total" : 6154, "updated" : 3500, "created" : 0, "deleted" : 0, "batches" : 4, "version_conflicts" : 0, "noops" : 0, "retries": { "bulk": 0, "search": 0 } "throttled_millis": 0 }, "description" : "" } } } } }
使用任務ID,您可以直接查找任務:
GET /_tasks/taskId:1
可以使用任務取消API取消任何按查詢更新:
POST _tasks/task_id:1/_cancel
手動切片:
POST twitter/_update_by_query { "slice": { "id": 0, "max": 2 }, "script": { "source": "ctx._source['extra'] = 'test'" } }
官方文檔參考:Update By Query API
10.Reindex API:重新索引
10.1.復制整個索引
最基本的形式_reindex
只是將文檔從一個索引復制到另一個索引。這會將twitter
索引中的文檔復制到new_twitter
索引中(前提是要有相同的索引類型):
POST _reindex { "source": { "index": "twitter" }, "dest": { "index": "new_twitter" } }
10.2.復制匹配的文檔
POST _reindex { "source": { "index": "twitter", "type": "_doc", "query": { "term": { "user": "kimchy" } } }, "dest": { "index": "new_twitter" } }
10.3.復制多個索引文檔
POST _reindex
{
"source": {
"index": ["book", "blog"],
"type": ["english", "user"]
},
"dest": {
"index": "book1"
}
}
ES 6.3只支持一個索引一個類型,所以上面這個並沒有實驗成功!提示:
"reason": "Rejecting mapping update to [book1] as the final mapping would have more than 1 type: [english, user]"
10.4.是否覆蓋版本號
POST reindex
{ "source": { "index": ["book"], "type": ["english"] }, "dest": { "index": "book1", "version_type":"external" } }
“external”:表示使用source的版本號覆蓋dest的版本號,當source的版本號<=dest的版本號會提示沖突,“internal”:表示保持dest的版本號自增。
10.5.只復制不存在的記錄,已經存在的記錄提示沖突
POST _reindex { "source": { "index": ["book"], "type": ["english"] }, "dest": { "index": "book1", "op_type": "create" } }
默認情況下,版本沖突會中止該_reindex
過程,但可以通過"conflicts": "proceed"
請求正文中的設置對它們進行計數
10.6.排序復制指定數量
POST _reindex
{ "size":10, "source": { "index": ["book"], "sort": { "name": "desc" } }, "dest": { "index": "book1", "op_type": "create" } }
如果報錯禁止排序:Fielddata is disabled on text fields by...
聚合這些操作用單獨的數據結構(fielddata)緩存到內存里了,需要單獨開啟:
PUT book/_mapping/english { "properties": { "name": { "type": "text", "fielddata": true } } }
10.7.復制部分字段
POST _reindex {"source": { "index": "book", "_source": ["age", "name"] }, "dest": { "index": "book1" } }
10.8.過濾修改元數據再復制
POST _reindex
{ "size":2, "source": { "index": "book", "_source": ["age", "name"] }, "dest": { "index": "book1",
"routing": "=age" // 根據age進行路由
}, "script": { "source": "if (ctx._source.age == 12) {ctx._source.age++}", "lang": "painless" } }
就像在_update_by_query
,您可以設置ctx.op
更改在目標索引上執行的操作:
-
noop
-
設置
ctx.op = "noop"
腳本是否確定不必在目標索引中編制索引。這種無操作將noop
在 響應機構 的計數器中報告。 -
delete
-
ctx.op = "delete"
如果腳本確定必須從目標索引中刪除文檔,請進行 設置 。
10.9.從遠程復制
POST _reindex { "source": { "remote": { "host": "http://otherhost:9200", "username": "user", "password": "pass" }, "index": "source", "query": { "match": { "test": "data" } } }, "dest": { "index": "dest" } }
10.10.查看重建索引任務
GET _tasks?detailed=true&actions=*reindex
官方文檔參考:Reindex API
11.term Vectors:分詞api
11.1. term的基本信息
# term_freq:在在該字段中的頻率
# position:詞在該字段中的位置
# start_offset:從什么偏移量開始的
# end_offset: 到什么偏移量結束
11.2 term的統計信息
如果啟用了term的統計信息,即term_statistics設為true,那么有哪些統計信息呢?
11.3字段的統計信息
如果啟用了字段統計信息,即field_statistics設為true,那么有哪些統計信息呢?
# sum_doc_freq: 一個字段中所有term的文檔頻率之和
# doc_count: 有多少個文檔包含這個字段
# sum_ttf:sum total term frequency的縮寫,一個字段中的每一個term的在所有文檔出現之和
term statistics和field statistics並不精准,不會被考慮有的doc可能被刪除了
11.5采集term信息的方式
采集term信息的方式有兩種:index-time(從已經存儲的索引中查看) 和 query-time(及時生成)
11.6 index-time方式
需要在mapping配置一下,然后建立索引的時候,就直接生成這些詞條和文檔的統計信息

PUT /website { "mappings": { "article":{ "properties":{ "text":{ "type": "text", "term_vector": "with_positions_offsets", "store": "true", "analyzer" : "fulltext" } } } }, "settings": { "analysis": { "analyzer": { "fulltext":{ "type": "custom", "tokenizer": "whitespace", "filter": [ "lowercase", "type_as_payload" ] } } } } }
11.7 query-time方式
即之前沒有在mapping里配置過,而是通過查詢的方式產生這些統計信息
POST /ecommerce/music/1/_termvectors { "fields":["desc"], "offsets":true, "payloads":true, "positions":true, "term_statistics":true, "field_statistics" : true }
11.8 手動指定analyzer來生成termvector
我么可以通過指定per_field_analyzer設置一個分詞器對該字段文本進行分詞。
POST /ecommerce/music/1/_termvectors { "fields":["desc"], "offsets":true, "payloads":true, "positions":true, "term_statistics":true, "field_statistics" : true, "per_field_analyzer":{ "text":"standard" } }
11.9 在線文檔及時生成termvector
POST book/english/_termvectors { "doc" : { "name" : "hellow word", "text" : "twitter test test test" }, "fields": ["name"], "per_field_analyzer" : { "name":"standard" } }
response

{ "_index": "book", "_type": "english", "_version": 0, "found": true, "took": 1, "term_vectors": { "name": { "field_statistics": { "sum_doc_freq": 632, "doc_count": 30, "sum_ttf": 991 }, "terms": { "hellow": { "term_freq": 1, "tokens": [ { "position": 0, "start_offset": 0, "end_offset": 6 } ] }, "word": { "term_freq": 1, "tokens": [ { "position": 1, "start_offset": 7, "end_offset": 11 } ] } } } } }
11.10 term的統計信息
我們可以根據term的統計信息,過濾出我么想看的統計結果,比如過濾掉一些出現頻率過低的term,比如我要過濾出該字段最多只有10個term,而且那些term在該字段中出現的頻率為2,且
POST /ecommerce/music/1/_termvectors { "fields":["desc"], "offsets":true, "payloads":true, "positions":true, "term_statistics":true, "field_statistics" : true,
"filter":{ "max_num_terms":10, // 返回的最大分詞輸 "min_term_freq" : 2, // 忽略低於源文檔中出現的次數 "min_doc_freq" : 1 // 忽略低於所有文檔中出現的次數 }
}
11.11 term過濾參數說明
max_num_terms:每個字段必須返回的最大分詞數。默認為25。 min_term_freq:忽略源文檔中低於此頻率的單詞。默認為1。 max_term_freq:忽略源文檔中超過此頻率的單詞。默認為無限制。 min_doc_freq:忽略至少在這么多文檔中沒有出現的分詞。默認為1。 max_doc_freq:忽略超過這么多文檔中出現的單詞。默認為無限制。 min_word_length:最小字長,低於該字長將被忽略。默認為0。 max_word_length:最大字長,高於該字長將被忽略。默認為unbounded(0)。
官方文檔參考:Term Vector Api
12 批量返回分詞:Multi termvectors API
采集term信息的方式有兩種:index-time(從已經存儲的索引中查看) 和 query-time(及時生成)
12.1 index-time

POST /_mtermvectors { "docs": [ { "_index": "twitter", "_type": "_doc", "_id": "2", "term_statistics": true }, { "_index": "twitter", "_type": "_doc", "_id": "1", "fields": [ "message" ] } ] }
url中指定索引:

POST /twitter/_mtermvectors { "docs": [ { "_type": "_doc", "_id": "2", "fields": [ "message" ], "term_statistics": true }, { "_type": "_doc", "_id": "1" } ] }
url中指定索引類型:

POST /twitter/_doc/_mtermvectors { "docs": [ { "_id": "2", "fields": [ "message" ], "term_statistics": true }, { "_id": "1" } ] }
如果索引類型和字段都相同:

POST /twitter/_doc/_mtermvectors { "ids" : ["1", "2"], "parameters": { "fields": [ "message" ], "term_statistics": true } }
12.2及時批量生成

POST_mtermvectors { "docs": [ { "_index": "book", "_type": "english", "doc" : { "name" : "John Doe", "message" : "twitter test test test" }, "fields": ["name"], "per_field_analyzer" : { "name":"standard" } }, { "_index": "book", "_type": "english", "doc" : { "name" : "Jane Doe", "message" : "Another twitter test ..." }, "fields": ["name"], "per_field_analyzer" : { "name":"standard" } } ] }
response:

{ "docs": [ { "_index": "book", "_type": "english", "_version": 0, "found": true, "took": 2, "term_vectors": { "name": { "field_statistics": { "sum_doc_freq": 632, "doc_count": 30, "sum_ttf": 991 }, "terms": { "doe": { "term_freq": 1, "tokens": [ { "position": 1, "start_offset": 5, "end_offset": 8 } ] }, "john": { "term_freq": 1, "tokens": [ { "position": 0, "start_offset": 0, "end_offset": 4 } ] } } } } }, { "_index": "book", "_type": "english", "_version": 0, "found": true, "took": 0, "term_vectors": { "name": { "field_statistics": { "sum_doc_freq": 632, "doc_count": 30, "sum_ttf": 991 }, "terms": { "doe": { "term_freq": 1, "tokens": [ { "position": 1, "start_offset": 5, "end_offset": 8 } ] }, "jane": { "term_freq": 1, "tokens": [ { "position": 0, "start_offset": 0, "end_offset": 4 } ] } } } } } ] }
12.2.返回該索引全部文檔的分詞統計
POST book/_search
{
"size" : 0, "aggs" : { "messages" : { "terms" : { "size" : 10, "field" : "name" } } } }
官方文檔參考:Multi termvectors API
13.?refresh
ES的索引數據是寫入到磁盤上的。但這個過程是分階段實現的,因為IO的操作是比較費時的。
- 先寫到內存中,此時不可搜索
- 默認經過 1s 之后會(refresh)被寫入 lucene 的底層文件 segment 中 ,此時可以搜索到
- flush之后才會寫入磁盤
以上過程由於隨時可能被中斷導致數據丟失,所以每一個過程都會有 translog 記錄,如果中間有任何一步失敗了,等服務器重啟之后就會重試,保證數據寫入。translog也是先存在內存里的,然后默認5秒刷一次寫到硬盤里。
在 index ,Update , Delete , Bulk 等操作中,可以設置 refresh 的值。取值如下:
13.1.refresh=true
更新數據之后,立刻對相關的分片(包括副本) 刷新,這個刷新操作保證了數據更新的結果可以立刻被搜索到。
13.2.refresh=wait_for
這個參數表示,刷新后返回。刷新不會立刻進行,而是等待一段時間才刷新 ( index.refresh_interval
),默認時間是 1 秒。刷新時間間隔可以通過index 的配置動態修改。或者直接手動刷新 POST /twitter/_refresh
13.3.refresh=false
refresh 的默認值,立即返回。更新數據之后不立刻刷新,在返回結果之后的某個時間點會自動刷新,也就是隨機的,看es服務器的運行情況。
那么選擇哪種刷新方式?
-
wait_for 和 true 對比,前者每次會積累一定的工作量再去刷新
-
true 是低效的,因為每次實時刷新會產生很小的 segment,隨后這些零碎的小段會被合並到效率更高的大 segment 中。也就是說使用 true 的代價在於,在 index 階段會創建這些小的 segment,在搜索的時候也是搜索這些小的 segment,在合並的時候去將小的 segment 合並到大的 segment 中
-
不要在多個請求中對每一條數據都設置
refresh=wait_for
, 用bulk 去批量更新,然后在單個的請求中設置refresh=wait_for
會好一些 -
如果
index.refresh_interval: -1
,將會禁用刷新,那帶上了refresh=wait_for
參數的請求實際上刷新的時間是未知的。如果index.refresh_interval
的值設置的比默認值( 1s )更小,比如 200 ms,那帶上了refresh=wait_for
參數的請求將很快刷新,但是仍然會產生一些低效的segment。 -
refresh=wait_for
只會影響到當前需要強制刷新的請求,refresh=true
卻會影響正在處理的其他請求。所以如果想盡可能小的縮小影響范圍時,應該用refresh=wait_for
官方文檔參考:Refresh api