<commit_before>[[docs-update-by-query]]
== Update By Query API

experimental[The update-by-query API is new and should still be considered experimental.  The API may change in ways that are not backwards compatible]

The simplest usage of `_update_by_query` just performs an update on every
document in the index without changing the source. This is useful to
<<picking-up-a-new-property,pick up a new property>> or some other online
mapping change. Here is the API:

[source,js]
--------------------------------------------------
POST twitter/_update_by_query?conflicts=proceed
--------------------------------------------------
// CONSOLE
// TEST[setup:big_twitter]

That will return something like this:

[source,js]
--------------------------------------------------
{
  "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" : [ ]
}
--------------------------------------------------
// TESTRESPONSE[s/"took" : 147/"took" : "$body.took"/]

`_update_by_query` gets a snapshot of the index when it starts and indexes what
it finds using `internal` versioning. That means that you'll get a version
conflict if the document changes between the time when the snapshot was taken
and when the index request is processed. When the versions match the document
is updated and the version number is incremented.

NOTE: Since `internal` versioning does not support the value 0 as a valid
version number, documents with version equal to zero cannot be updated using
`_update_by_query` and will fail the request.

All update and query failures cause the `_update_by_query` to abort and are
returned in the `failures` of the response. The updates that have been
performed still stick. In other words, the process is not rolled back, only
aborted. While the first failure causes the abort all failures that are
returned by the failing bulk request are returned in the `failures` element so
it's possible for there to be quite a few.

If you want to simply count version conflicts not cause the `_update_by_query`
to abort you can set `conflicts=proceed` on the url or `"conflicts": "proceed"`
in the request body. The first example does this because it is just trying to
pick up an online mapping change and a version conflict simply means that the
conflicting document was updated between the start of the `_update_by_query`
and the time when it attempted to update the document. This is fine because
that update will have picked up the online mapping update.

Back to the API format, you can limit `_update_by_query` to a single type. This
will only update `tweet` documents from the `twitter` index:

[source,js]
--------------------------------------------------
POST twitter/tweet/_update_by_query?conflicts=proceed
--------------------------------------------------
// CONSOLE
// TEST[setup:twitter]

You can also limit `_update_by_query` using the
<<query-dsl,Query DSL>>. This will update all documents from the
`twitter` index for the user `kimchy`:

[source,js]
--------------------------------------------------
POST twitter/_update_by_query?conflicts=proceed
{
  "query": { <1><commit_msg>clarify ambiguous sentence. (#21734)<commit_after>[[docs-update-by-query]]
== Update By Query API

experimental[The update-by-query API is new and should still be considered experimental.  The API may change in ways that are not backwards compatible]

The simplest usage of `_update_by_query` just performs an update on every
document in the index without changing the source. This is useful to
<<picking-up-a-new-property,pick up a new property>> or some other online
mapping change. Here is the API:

[source,js]
--------------------------------------------------
POST twitter/_update_by_query?conflicts=proceed
--------------------------------------------------
// CONSOLE
// TEST[setup:big_twitter]

That will return something like this:

[source,js]
--------------------------------------------------
{
  "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" : [ ]
}
--------------------------------------------------
// TESTRESPONSE[s/"took" : 147/"took" : "$body.took"/]

`_update_by_query` gets a snapshot of the index when it starts and indexes what
it finds using `internal` versioning. That means that you'll get a version
conflict if the document changes between the time when the snapshot was taken
and when the index request is processed. When the versions match the document
is updated and the version number is incremented.

NOTE: Since `internal` versioning does not support the value 0 as a valid
version number, documents with version equal to zero cannot be updated using
`_update_by_query` and will fail the request.

All update and query failures cause the `_update_by_query` to abort and are
returned in the `failures` of the response. The updates that have been
performed still stick. In other words, the process is not rolled back, only
aborted. While the first failure causes the abort, all failures that are
returned by the failing bulk request are returned in the `failures` element; therefore
it's possible for there to be quite a few failed entities.

If you want to simply count version conflicts not cause the `_update_by_query`
to abort you can set `conflicts=proceed` on the url or `"conflicts": "proceed"`
in the request body. The first example does this because it is just trying to
pick up an online mapping change and a version conflict simply means that the
conflicting document was updated between the start of the `_update_by_query`
and the time when it attempted to update the document. This is fine because
that update will have picked up the online mapping update.

Back to the API format, you can limit `_update_by_query` to a single type. This
will only update `tweet` documents from the `twitter` index:

[source,js]
--------------------------------------------------
POST twitter/tweet/_update_by_query?conflicts=proceed
--------------------------------------------------
// CONSOLE
// TEST[setup:twitter]

You can also limit `_update_by_query` using the
<<query-dsl,Query DSL>>. This will update all documents from the
`twitter` index for the user `kimchy`:

[source,js]
--------------------------------------------------
POST twitter/_update_by_query?conflicts=proceed
{
  "query": { <1>
{'fraction_non_alphanumeric': 0.1727326968973747, 'fraction_numerical': 0.007905727923627684, 'mean_word_length': 2.781725888324873, 'pattern_counts': {'":': 30, '<': 13, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4430957', 'n_tokens_mistral': 1848, 'n_tokens_neox': 1755, 'n_words': 828}