1、使用ElasticSearch API 實現CRUD
(1)添加索引:
PUT /lib/
{
"settings":{
"index":{
"number_of_shards": 5,
"number_of_replicas": 1
}
}
}
查看索引信息:
GET /lib/_settings
GET _all/_settings
(2)添加文檔:
# 手動設置ID
PUT /lib/user/1
{
"first_name" : "Jane",
"last_name" : "Smith",
"age" : 32,
"about" : "I like to collect rock albums",
"interests": [ "music" ]
}
# 自動生成ID
POST /lib/user/
{
"first_name" : "Douglas",
"last_name" : "Fir",
"age" : 23,
"about": "I like to build cabinets",
"interests": [ "forestry" ]
}
查看文檔:
GET /lib/user/1
GET /lib/user/
GET /lib/user/1?_source=age,interests
(3)更新文檔:
# 覆蓋更新
PUT /lib/user/1
{
"first_name" : "Jane",
"last_name" : "Smith",
"age" : 36,
"about" : "I like to collect rock albums",
"interests": [ "music" ]
}
# 修改原有內容進行更新
POST /lib/user/1/_update
{
"doc":{
"age":33
}
}
(4)刪除一個文檔
DELETE /lib/user/1
刪除一個索引
DELETE /lib
2、批量獲取文檔
使用es提供的Multi Get API:
使用Multi Get API可以通過索引名、類型名、文檔id一次得到一個文檔集合,文檔可以來自同一個索引庫,也可以來自不同索引庫
# 批量獲取字段
GET /_mget
{
"docs":[
{
"_index":"lib",
"_type":"user",
"_id":1
},
{
"_index":"lib",
"_type":"user",
"_id":2
},
{
"_index":"lib",
"_type":"user",
"_id":3
}
]
}
# 批量獲取指定字段值
GET /_mget
{
"docs":[
{
"_index":"lib",
"_type":"user",
"_id":1,
"_source":"interests"
},
{
"_index":"lib",
"_type":"user",
"_id":2,
"_source":["age","interests"]
}
]
}
# 簡化獲取方式(索引和類型相同情況下)
GET /lib/user/_mget
{
"ids":["1","2","3"]
}
3、使用Bulk API 實現批量操作
(1)bulk的格式:
{action:{metadata}}\n
{requstbody}\n
(2)action:(行爲)
create:文檔不存在時創建
update:更新文檔
index:創建新文檔或替換已有文檔
delete:刪除一個文檔
metadata:_index,_type,_id
(3)create 和index的區別
如果數據存在,使用create操作失敗,會提示文檔已經存在,使用index則可以成功執行。
(4)示例:
# 同時添加多個文檔
POST /lib2/books/_bulk
{"index":{"_id":1}}
{"title":"java","price":55}
{"index":{"_id":2}}
{"title":"python","price":46}
{"index":{"_id":3}}
{"title":"php","price":66}
{"index":{"_id":4}}
{"title":"C#","price":88}
# 查看新添加文檔
GET /lib2/books/_mget
{
"ids":["1","2","3","4","100"]
}
# 一次處理多個請求
POST /lib2/books/_bulk
{"delete":{"_index":"lib2","_type":"books","_id":4}}
{"create":{"_index":"tt","_type":"ttt","_id":"100"}}
{"name":"lisi"}
{"index":{"_index":"tt","_type":"ttt"}}
{"name":"zhaosi"}
{"update":{"_index":"lib2","_type":"books","_id":3}}
{"doc":{"price":58}}
GET /tt/ttt/_mget
{
"ids":["100","hY9WEG4BqNl6gJJm4VhG"]
}
刪除:沒有請求體
POST /lib2/books/_bulk
{"delete":{"_index":"lib2","_type":"books","_id":4}}
{"create":{"_index":"tt","_type":"ttt","_id":"100"}}
{"name":"lisi"}
{"index":{"_index":"tt","_type":"ttt"}}
{"name":"zhaosi"}
{"update":{"_index":"lib2","_type":"books","_id":"4"}}
{"doc":{"price":58}}
bulk一次最大處理多少數據量:
bulk會把將要處理的數據載入內存中,所以數據量是有限制的,最佳的數據量不是一個確定的數值,它取決於你的硬件,你的文檔大小以及複雜性,你的索引以及搜索的負載。
一般建議是1000-5000個文檔,大小建議是5-15MB,默認不能超過100M,可以在es的配置文件(即$ES_HOME下的config下的elasticsearch.yml)中。
4、版本控制
ElasticSearch採用了樂觀鎖來保證數據的一致性,也就是說,當用戶對document進行操時,並不需要對該document作加鎖和解鎖的操作,只需要指定要操作的版本即可。當版本號一致時,ElasticSearch會允許該操作順利執行,而當版本號存在衝突時,ElasticSearch會提示衝突並拋出異常(VersionConflictEngineException異常)。
ElasticSearch的版本號的取值範圍爲1到2^63-1。
內部版本控制:使用的是_version
外部版本控制:elasticsearch在處理外部版本號時會與對內部版本號的處理有些不同。它不再是檢查_version是否與請求中指定的數值_相同_,而是檢查當前的_version是否比指定的數值小。如果請求成功,那麼外部的版本號就會被存儲到文檔中的_version中。
爲了保持_version與外部版本控制的數據一致使用version_type=external
示例:
# 版本控制(內部版本控制使用_version)
PUT /lib/user/4
{"first_name":"Jane",
"last_name":"Lily",
"age":16,
"about":"I like to play computer",
"interests":["music"]
}
# 修改年齡,版本號自動加1
PUT /lib/user/4
{"first_name":"Jane",
"last_name":"Lily",
"age":16,
"about":"I like to play computer",
"interests":["music"]
}
PUT /lib/user/4?version=3
{"first_name":"Jane",
"last_name":"Lily",
"age":33,
"about":"I like to play computer",
"interests":["music"]
}
# 外部版本控制version_type
PUT /lib/user/4?version=4&version_type=external
{"first_name":"Jane",
"last_name":"Lily",
"age":33,
"about":"I like to play computer",
"interests":["music"]
}
5、什麼是Mapping
ES的mapping非常類似於靜態語言中的數據類型:聲明一個變量爲int類型的變量, 以後這個變量都只能存儲int類型的數據。同樣的, 一個number類型的mapping字段只能存儲number類型的數據。
同語言的數據類型相比,mapping還有一些其他的含義,mapping不僅告訴ES一個field中是什麼類型的值, 它還告訴ES如何索引數據以及數據是否能被搜索到。
當你的查詢沒有返回相應的數據, 你的mapping很有可能有問題。當你拿不準的時候, 直接檢查你的mapping。
代碼示例:
# mapping學習(自動檢測字段數據類型)動態映射
# 支持的數據類型,字符型:string,包括text和keyword
# text類型被用來索引長文本,在簡歷索引前會將這些文本進行分詞,轉化爲詞的組合,建立索引,允許es來檢索這些詞語,text類型不能用來排序和聚合
# keyword類型不需要進行分詞,可以被用來檢索過濾,排序和聚合;keyword類型字段只可以用本身來進行檢索。
# 數字型:long,integer,short,byte,double,float
# 日期型:date
# 布爾型:boolean
# 二進制型:binary
PUT /myindex/article/1
{
"post_date":"2018-05-10",
"title":"java",
"content":"java is the best language",
"author_id":120
}
PUT /myindex/article/2
{
"post_date":"2018-05-10",
"title":"html",
"content":"I like html",
"author_id":119
}
PUT /myindex/article/3
{
"post_date":"2018-05-10",
"title":"es",
"content":"Es is dietributed document store",
"author_id":110
}
# 自動檢測數據類型
# true,false-->boolean
# "sssdd"-->string
# 119-->long
# 123.33-->double
# 1990-12-12-->date
# 查看es自動創建的mapping
GET /myindex/article/_mapping
GET /myindex/article/_search
# 查不出來
GET /myindex/article/_search?q=post_date:2018
# 查出來(數值日期需要精確查詢)
GET /myindex/article/_search?q=post_date:2018-05-10
# 字符串類型匹配查詢(默認分詞)
GET /myindex/article/_search?q=content:html
# object類型
PUT /lib5/person/1
{
"name":"tom",
"age":25,
"birthday":"1998-08-08",
"address":{
"country":"china",
"province":"lanzhou",
"city":"chengguan"
}
}
GET /lib5/person/_mapping
# 手動創建mapping
PUT /lib6
{
"settings":{
"number_of_shards" : 3,
"number_of_replicas" : 0
},
"mappings":{
"books":{
"properties":{
"title":{"type":"text"},
"name":{"type":"text","analyzer":"standard"},
"publish_date":{"type":"date","index":false},
"price":{"type":"double"},
"number":{"type":"integer"}
}
}
}
}
GET /lib6
DELETE /lib6
es自動創建了index,type,以及type對應的mapping(dynamic mapping)
什麼是映射:mapping定義了type中的每個字段的數據類型以及這些字段如何分詞等相關屬性
{
"myindex": {
"mappings": {
"article": {
"properties": {
"author_id": {
"type": "long"
},
"content": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"post_date": {
"type": "date"
},
"title": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
}
}
}
創建索引的時候,可以預先定義字段的類型以及相關屬性,這樣就能夠把日期字段處理成日期,把數字字段處理成數字,把字符串字段處理字符串值等。
支持的數據類型:
(1)核心數據類型(Core datatypes)
字符型:string,string類型包括
text 和 keyword
text類型被用來索引長文本,在建立索引前會將這些文本進行分詞,轉化爲詞的組合,建立索引。允許es來檢索這些詞語。text類型不能用來排序和聚合。
Keyword類型不需要進行分詞,可以被用來檢索過濾、排序和聚合。keyword 類型字段只能用本身來進行檢索
數字型:long, integer, short, byte, double, float
日期型:date
布爾型:boolean
二進制型:binary
(2)複雜數據類型(Complex datatypes)
數組類型(Array datatype):數組類型不需要專門指定數組元素的type,例如:
字符型數組: [ "one", "two" ]
整型數組:[ 1, 2 ]
數組型數組:[ 1, [ 2, 3 ]] 等價於[ 1, 2, 3 ]
對象數組:[ { "name": "Mary", "age": 12 }, { "name": "John", "age": 10 }]
對象類型(Object datatype):_ object _ 用於單個JSON對象;
嵌套類型(Nested datatype):_ nested _ 用於JSON數組;
(3)地理位置類型(Geo datatypes)
地理座標類型(Geo-point datatype):_ geo_point _ 用於經緯度座標;
地理形狀類型(Geo-Shape datatype):_ geo_shape _ 用於類似於多邊形的複雜形狀;
映射的分類:
(1)動態映射:
當ES在文檔中碰到一個以前沒見過的字段時,它會利用動態映射來決定該字段的類型,並自動地對該字段添加映射。
可以通過dynamic設置來控制這一行爲,它能夠接受以下的選項:
true:默認值。動態添加字段
false:忽略新字段
strict:如果碰到陌生字段,拋出異常
dynamic設置可以適用在根對象上或者object類型的任意字段上。
POST /lib6
#給索引lib2創建映射類型
{
"settings":{
"number_of_shards" : 3,
"number_of_replicas" : 0
},
"mappings":{
"books":{
"properties":{
"title":{"type":"text"},
"name":{"type":"text","index":false},
"publish_date":{"type":"date","index":false},
"price":{"type":"double"},
"number":{"type":"integer"}
}
}
}
}
POST /lib6
#給索引lib2創建映射類型
{
"settings":{
"number_of_shards" : 3,
"number_of_replicas" : 0
},
"mappings":{
"books":{
"properties":{
"title":{"type":"text"},
"name":{"type":"text","index":false},
"publish_date":{"type":"date","index":false},
"price":{"type":"double"},
"number":{
"type":"object",
"dynamic":true
}
}
}
}
}