iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 11
0

Day 11 為建構好的index增加document


前言

昨天我們講解了什麼是index,以及關於index層級的一些基本操作(後面還有一些操作,像是split、merge或是index template,有時間會再提)。今天我們會講解如何將資料餵進去index中,而我們稱這些資料,每一筆叫做一個document。基本上是以json的形式,去加入這些document。

Index Document

要將資料餵進去index,我們必須將這些document,傳送到index裡面。而這時候有兩種做法,可以使用_doc或是_create這兩種。這兩種有一些性質上的差異,等等會提到。

這邊順便提到一個之後會說的,除了這種將資料透過單個或一次批次request的方式傳遞,elasticsearch還有可以將data用streaming的方式傳遞,但這種datastream的方式,適合用在大量時序資料,且不需update(append only)的情況,這部份我們後續會特別開一天來講解。

_doc以及_create

首先在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

刪除Document

DELETE /demo-index/_doc/1

同樣也可以設置timeout

DELETE /demo-index/_doc/1?timeout=5m

取Document

接著是查看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更新document

最後講一下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讓大家操作!


上一篇
Day 10 Index API介紹及使用
下一篇
Day 12 Bulk upload document
系列文
親愛的,我把ElasticSearch上雲了30

尚未有邦友留言

立即登入留言