ingest pipelineはdoc_as_upsertではなくupsertと使う

ドキュメントを読みましょう、というだけなんですが…。

# noop update
elasticsearchのupdateには`noop update`という仕組みがあり、同じ内容のドキュメントでアップデートしようとしてもキャンセルされてアップデートは実施されず、インデクシングは生じない。これは、各ドキュメントの"_version"が上がらないことで確認できる。

```json
PUT /test_noop_update/

POST /test_noop_update/_doc/1
{
  "foo":"baa"
}

GET /test_noop_update/_doc/1

POST /test_noop_update/_update/1
{
  "doc":{
    "foo":"baa"
  }
}
```

```jsonc
{
  "_index" : "test_noop_update",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 1,
  "result" : "noop", //<--updateが実施されなかったことが分かる。
  "_shards" : {
    "total" : 0,
    "successful" : 0,
    "failed" : 0
  },
  "_seq_no" : 0,
  "_primary_term" : 1
}
```

```jsonc
GET /test_noop_update/_doc/1

{
  "_index" : "test_noop_update",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 1, //<-- 1のまま
  "_seq_no" : 0,
  "_primary_term" : 1,
  "found" : true,
  "_source" : {
    "foo" : "baa"
  }
}
```

# ingest_pipelineとdoc_as_upsertを併用すると、noop updateにならないことがある
Logstashを利用してupdateする際に文書の重複への対処としてIDをfingerprintで採番してdoc_idを付与していたのだが、同じ内容の文書であってもアップデートされてしまい、"_version"が変わってしまっていた。

elasticsearch単体で実験してみると、

```jsonc
PUT /test_noop_update/
{
  "settings": {
    "index":{
      "default_pipeline": "last_updated_timestamp_pipeline"
    }
  }
}

POST /test_noop_update/_doc/1
{
  "foo":"baa"
}

POST /test_noop_update/_bulk
{"update":{"_id":1}}
{"doc": {"foo":"baa"}}
{"update":{"_id":1}}
{"doc": {"foo":"baa"}, "doc_as_upsert":true}
{"update":{"_id":1}}
{"doc": {"foo":"baa"}, "upsert":{}}
```

```jsonc
{
  "took" : 19,
  "ingest_took" : 0,
  "errors" : false,
  "items" : [
    {
      "update" : {
        "_index" : "test_noop_update",
        "_type" : "_doc",
        "_id" : "1",
        "_version" : 1,
        "result" : "noop", //<--ok
        "_shards" : {
          "total" : 2,
          "successful" : 2,
          "failed" : 0
        },
        "_seq_no" : 0,
        "_primary_term" : 1,
        "status" : 200
      }
    },
    {
      "update" : {
        "_index" : "test_noop_update",
        "_type" : "_doc",
        "_id" : "1",
        "_version" : 2,
        "result" : "updated", //<-- doc_as_upsert使用時のみ"updated"に。
        "_shards" : {
          "total" : 2,
          "successful" : 2,
          "failed" : 0
        },
        "_seq_no" : 1,
        "_primary_term" : 1,
        "status" : 200
      }
    },
    {
      "update" : {
        "_index" : "test_noop_update",
        "_type" : "_doc",
        "_id" : "1",
        "_version" : 2,
        "result" : "noop", //<--ok
        "_shards" : {
          "total" : 2,
          "successful" : 2,
          "failed" : 0
        },
        "_seq_no" : 1,
        "_primary_term" : 1,
        "status" : 200
      }
    }
  ]
}

```
doc_as_upsert使用時のみ"updated"になっている。まとめると、

## ingest_pipelineなし

| action | parameter | _version
|---|---|---
|index||+1
|update||-
|update|upsert:{}|-
|update|doc_as_upsert|-

## ingest_pipelineあり

| action | parameter | _version
|---|---|---
|index||+1
|update||-
|update|upsert:{}|-
|update|doc_as_upsert|**+1**

と、ingest_piplineを併用している場合、`doc_as_upsert`のみ`noop update`が生じずに、同じdocumentにも関わらず通常のupdateが発生してしまっていた（なおこの挙動は毎回生じるものなのか、ingest pipelineの内容といった状況次第なのかは分からない）。

ここで初めてelasticsearch側のドキュメントを確認すると、
> NOTE: Using ingest pipelines with doc_as_upsert is not supported.

https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-update.html#doc_as_upsert

とあり、どうやら`ingest_pipeline`と`doc_as_upsert`を同時に使用することは非推奨で、`upsert`を使いましょう、ということでした。`upsert`でドキュメントと同じ内容のjsonを指定すると同じ効果が得られます。

#教訓
ドキュメントをきちんと読みましょう。