ある記事では、Elasticsearchを更新する方法を説明しています(クエリによるUpdataとUpdata)

序文

Elasticsearch操作の中で、最も一般的に使用されるのは検索および更新操作です。以前にElasticsearchの検索APIを紹介したので、本日はElasticsearchの更新操作を紹介します。

APIアップデート

Elasticsearchの更新APIはUpdateであり、URLの_updateメソッドであり、Updateメソッドはスクリプトの更新とコンテンツの更新をサポートします

更新APIを使用すると、提供されたスクリプトに基づいてドキュメントを更新できます。この操作は、インデックスからドキュメントを取得し(シャードと併置)、スクリプトを実行し(オプションのスクリプト言語とパラメーターを使用)、結果にインデックスを付けます(削除または無視操作も許可されます)。バージョン管理を使用して、「取得」および「再インデックス」期間中に更新が発生しないようにします。

この操作は、ドキュメントの完全なインデックスの再作成を意味し、ネットワークのラウンドトリップを削除するだけで、getとindexの間でバージョンの競合が発生する可能性を減らすことに注意してください。この機能を正しく機能させるには、_sourceフィールドを有効にする必要があります。

たとえば、簡単なドキュメントにインデックスを付けましょう。

PUT test/_doc/1
{
    
    
    "counter" : 1,
    "tags" : ["red"]
}

以下では、このドキュメントを例として使用して、いくつかの一般的な更新操作を実行します。

スクリプトの更新

これで、カウンターをインクリメントするスクリプトを実行できます。

POST test/_doc/1/_update
{
    
    
    "script" : {
    
    
        "source": "ctx._source.counter += params.count",
        "lang": "painless",
        "params" : {
    
    
            "count" : 4
        }
    }
}

タグリスト(タグ)にタグを追加できます(タグが存在する場合でも、リストであるため追加されます)。

POST test/_doc/1/_update
{
    
    
    "script" : {
    
    
        "source": "ctx._source.tags.add(params.tag)",
        "lang": "painless",
        "params" : {
    
    
            "tag" : "blue"
        }
    }
}

注:ctx._sourceは、現在のドキュメントを表すために使用され、その後にドキュメント属性が続きます。カウンターの追加、タグの追加など、ドキュメント属性を変更できます。

_sourceに加えて、次のパラメーターもcxtマップに存在します:_index、_type、_id、_version、_routing、および_now(現在のタイムスタンプ)

ドキュメントに新しいフィールドを追加します。

POST test/_doc/1/_update
{
    
    
    "script" : "ctx._source.new_field = 'value_of_new_field'"
}

new_fieldは新しいフィールドの名前ですvalue_of_new_fieldはフィールド
の初期値です

フィールドを削除します。

POST test/_doc/1/_update
{
    
    
    "script" : "ctx._source.remove('new_field')"
}

単純な更新に加えて、スクリプトを使用して、次の例などの複雑な更新操作を実行することもできます。タグフィールドに緑色が含まれている場合、この例ではドキュメントが削除されます。それ以外の場合、操作は実行されません(noop)

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"
        }
    }
}

ctx.op = 'delete'は、ドキュメント内のデータを削除することを意味します
ctx.op = 'none'は、操作がないことを意味します

部分的なドキュメントで更新

スクリプトを使用して更新することに加えて、updateはドキュメントコンテンツの一部を使用した更新もサポートします。
更新APIは、既存のドキュメントにマージされるドキュメントの一部の転送をサポートします。既存のドキュメントを完全に置き換えるには、インデックスAPIを使用する必要があります。以下は、更新ドキュメントのフィールド値です。

POST test/_doc/1/_update
{
    
    
    "doc" : {
    
    
        "name" : "new_name"
    }
}

注:ドキュメントに名前フィールドがない場合は、最初に名前フィールドが追加され、次にnew_nameが割り当てられます。

複数のフィールドの更新

   {
    
    
    
      "doc" : {
    
    
        "new_field " : "new",
        "name":"m"
    }

docは、ドキュメントを再定義することと同じです。docを実行すると、ドキュメント内のデータがdocで定義されたデータになるため、docで直接データを更新および追加できます。

注:docとscriptの両方が指定されている場合、docは無視されます。

デフォルトでは、何も変更しない更新は、何も変更していないことを検出し、以下に示すように「result」:「noop」を返します。

POST test/_doc/1/_update
{
    
    
    "doc" : {
    
    
        "name" : "new_name"
    }
}

リクエストを送信する前にnameがnew_nameの場合、更新リクエスト全体が無視されます。リクエストが無視された場合、レスポンスの結果要素はnoopを返します。

{
    
    
   "_shards": {
    
    
        "total": 0,
        "successful": 0,
        "failed": 0
   },
   "_index": "test",
   "_type": "_doc",
   "_id": "1",
   "_version": 6,
   "result": "noop"
}

パラメータ

更新操作は、次のクエリ文字列パラメーターをサポートします。

retry_on_conflict	在更新的get和indexing阶段之间,另一个进程可能已经更新了同一文档。 默认情况下,更新将因版本冲突异常而失败。 retry_on_conflict	参数控制在最终抛出异常之前重试更新的次数。

routing		路由用于将更新请求路由到正确的分片,并在更新的文档不存在时为upsert请求设置路由。 不能用于更新现有文档的路由。

timeout		超时等待碎片变为可用。

wait_for_active_shards	在继续更新操作之前需要处于活动状态的分片副本数。 详情请见此处。

refresh		控制何时此请求所做的更改对搜索可见。 看?refresh。

_source		允许控制是否以及如何在响应中返回更新的源。 默认情况下,不会返回更新的源。 请参阅源过滤了解详细信息

version		更新API在内部使用Elasticsearch的版本控制支持,以确保在更新期间文档不会更改。 您可以使用
version参数指定仅在文档版本与指定版本匹配时才更新文档。

クエリAPIによる更新

Updata APIは、単一のドキュメントを更新するためのものです。多くの場合、複数のドキュメントを更新する必要があります。現時点では、Updata by QueryAPIを使用する必要があります。クエリAPIによるUpdataは、条件を満たすすべてのドキュメントを更新します

クエリAPIによるUpdataの対応するメソッドは_update_by_queryです

_update_by_queryの最も簡単な使用法は、ソースを変更せずにインデックス内の各ドキュメントに対して更新を実行することです。これは、新しい属性やその他のオンラインマッピングの変更を取得するのに役立ちます。

例:

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" : [ ]
}

_update_by_queryは、インデックスの開始時にインデックスのスナップショットを取得し、内部バージョン管理を使用してコンテンツにインデックスを付けます。これは、スナップショットが作成されてからインデックス要求が処理されるまでの間にドキュメントが変更された場合、バージョンの競合が発生することを意味します。バージョンが一致すると、ドキュメントが更新され、バージョン番号が増加します。

注:内部バージョン管理は有効なバージョン番号として値0をサポートしていないため、_update_by_queryを使用してバージョンがゼロに等しいドキュメントを更新することはできず、要求は失敗します。

すべての更新とクエリの失敗により、_update_by_queryが中止され、応答が失敗すると戻ります。実行された更新はまだ存在します。つまり、プロセスはロールバックされず、中止されるだけです。最初の失敗によってアボートが発生すると、失敗したバッチ要求によって返されたすべての失敗が失敗要素に返されます。したがって、失敗したエンティティがかなり多くなる可能性があります。

_update_by_queryを中止せずにバージョンの競合を単純に計算したい場合は、URLでconflicts = progressを設定するか、リクエスト本文で「conflicts」:「proceed」を設定できます。、このパラメーターは上記の例で使用されています。

クエリDSLを使用して、_update_by_queryの更新範囲を制限できます。

次のように、_update_by_queryは、すべてのドキュメントではなく、ユーザーがキムキーなドキュメントのみを更新します。

POST twitter/_update_by_query?conflicts=proceed
{
    
    
  "query": {
    
                       // 1
    "term": {
    
    
      "user": "kimchy"
    }
  }
}

_update_by_queryは、ドキュメントを更新するためのスクリプトもサポートしています

以下のように、ユーザーがキムキーであるすべてのドキュメントの「いいね」に1を追加します

POST twitter/_update_by_query
{
    
    
  "script": {
    
    
    "source": "ctx._source.likes++",
    "lang": "painless"
  },
  "query": {
    
    
    "term": {
    
    
      "user": "kimchy"
    }
  }
}

_update_by_queryは_updateに似ていますが、_update_by_queryがDSLクエリを介して更新の範囲を指定できる点が異なります。

例:

スクリプトメソッドを使用して、次のようなインデックスの1つにあるすべてのドキュメントに新しいフィールドを追加します。

POST twitter/_update_by_query
{
    
    
  "script": {
    
    
    "source": "ctx._source['contact'] = \"139111111111\""
  }
}

上記の方法により、Twitterインデックス内のすべてのドキュメントに新しいフィールド連絡先が追加され、同じ値が与えられます

おすすめ

転載: blog.csdn.net/qq_36551991/article/details/110096269