昨天我們講解了什麼是index,以及關於index層級的一些基本操作(後面還有一些操作,像是split、merge或是index template,有時間會再提)。今天我們會講解如何將資料餵進去index中,而我們稱這些資料,每一筆叫做一個document。基本上是以json的形式,去加入這些document。
要將資料餵進去index,我們必須將這些document,傳送到index裡面。而這時候有兩種做法,可以使用_doc或是_create這兩種。這兩種有一些性質上的差異,等等會提到。
這邊順便提到一個之後會說的,除了這種將資料透過單個或一次批次request的方式傳遞,elasticsearch還有可以將data用streaming的方式傳遞,但這種datastream的方式,適合用在大量時序資料,且不需update(append only)的情況,這部份我們後續會特別開一天來講解。
首先在index中增加document的方式有兩種,分別是_doc以及_create。
首先先看一下兩個方式的寫法
首先是_doc的寫法
PUT /demo-index/_doc/<id>
{"name": "Aron"}
POST /demo-index/_doc
{"name": "Aron"}
再來是create的寫法
PUT /demo-index/_create/<id>
{"name": "Aron"}
POST /demo-index/_create/<id>
{"name": "Aron"}
首先先分別講解一下,_doc可以透過PUT或POST,差別在於若要不給id(自動往後補上ID)那就要使用POST,若給ID的話則用PUT;
_create部分則是都需要給予ID,PUT或是POST都可以,而兩者最大差別在於,或使用PUT,ID重複的狀態下,後面給予的會覆蓋前面的;_create則會直接回報已存在,差別如下
已存在id為1的document
PUT /demo-index/_create/1
response:
{
"error": {
"root_cause": [
{
"type": "version_conflict_engine_exception",
"reason": "[1]: version conflict, document already exists (current version [4])",
"index_uuid": "fpPffT1bQT6yr0GP6lYAeA",
"shard": "0",
"index": "demo-index"
}
],
PUT /demo-index/_doc/1
response:
{
"_index": "demo-index",
"_type": "_doc",
"_id": "1",
"_version": 5,
"result": "updated",
"_shards": {
"total": 2,
"successful": 2,
"failed": 0
},
"_seq_no": 7,
"_primary_term": 1
}
因此若是想要用後面的覆蓋前面的,就可以使用_doc,若是希望能夠check是否存在該id,則可以透過_create確認。
另外若避免分片忙碌,可以設置timeout,若超過時間則會放棄這次新增。
PUT /demo-index/_doc/1?timeout=5m
新增的大致上就是這樣,接下來刪除的部分則是跟index相同,只是把method改成DELETE
DELETE /demo-index/_doc/1
同樣也可以設置timeout
DELETE /demo-index/_doc/1?timeout=5m
接著是查看Document,可以透過_doc去檢視文件內容。
GET demo-index/_doc/1
這樣就取出id為1的document
{
"_index": "demo-index",
"_type": "_doc",
"_id": "1",
"_version": 6,
"_seq_no": 8,
"_primary_term": 1,
"found": true,
"_source": {
"name": "Aro2n"
}
}
而大家有沒有發現,Document中,包含一些有底線的,這些其實是內部預設的,像是_index、_type等等,而我們建構的json格式資料,存在_source中,因此也可以透過_source去取出這個資料
GET /demo-index/_source/1
{
"name": "Aro2n"
}
除此之外也可以取得特定欄位,我們先建構一個新的document,包含一個以上field
PUT /demo-index/_doc/1
{"name": "Aron", "age": 29, "job": "student"}
GET /demo-index/_doc/1?_source_includes=name,job
GET /demo-index/_doc/1?_sourcename,job
response:
{
"_index": "demo-index",
"_type": "_doc",
"_id": "1",
"_version": 7,
"_seq_no": 9,
"_primary_term": 1,
"found": true,
"_source": {
"name": "Aron",
"job": "student"
}
}
最後講一下update的部分,與前面PUT _doc差別在於,PUT _doc是有更新效果,但是是整個覆蓋,update則可以擴充原先的資料
POST demo-index/_update/1
{
"script" : {
"source": "ctx._source.counter += params.count",
"lang": "painless",
"params" : {
"count" : 4
}
}
}
POST /demo-index/_update/1
{"doc":{"name": "sron"}}
GET /demo-index/_doc/1
{
"_index": "demo-index",
"_type": "_doc",
"_id": "1",
"_version": 8,
"_seq_no": 10,
"_primary_term": 1,
"found": true,
"_source": {
"name": "sron",
"age": 29,
"job": "student"
}
}
明天會把bulk多筆上傳資料部分講完,接著會提到一下datastream,接下來幾天也會將一般log如何餵給ELK,用docker加上filebeat logstash呈現給大家,接下來比較多用到code部分,會附上github讓大家操作!