Skip to content

Commit 2f5589c

Browse files
committed
[API] Updates create endpoint for new behaviour.
The API now makes a request, instead of calling index like in previous versions (< 9.0.0). * `body`, `index` and `id` are now required parameters. * `op_type` is now a String parameter: Set to 'create' to only index the document if it does not already exist (put if absent). If a document with the specified '_id' already exists, the indexing operation will fail. The behavior is the same as using the '<index>/_create' endpoint. If a document ID is specified, this paramater defaults to 'index'. Otherwise, it defaults to `create`. If the request targets a data stream, an `op_type` of `create` is required. Additional new parameters: * :if_primary_term (Integer) - Only perform the operation if the document has this primary term. * :if_seq_no (Integer) - Only perform the operation if the document has this sequence number.
1 parent ffb9a0b commit 2f5589c

File tree

2 files changed

+132
-76
lines changed

2 files changed

+132
-76
lines changed

elasticsearch-api/lib/elasticsearch/api/actions/create.rb

Lines changed: 110 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -15,44 +15,131 @@
1515
# specific language governing permissions and limitations
1616
# under the License.
1717
#
18-
# Auto generated from build hash f284cc16f4d4b4289bc679aa1529bb504190fe80
19-
# @see https://github.com/elastic/elasticsearch/tree/main/rest-api-spec
18+
# Auto generated from commit f284cc16f4d4b4289bc679aa1529bb504190fe80
19+
# @see https://github.com/elastic/elasticsearch-specification
2020
#
2121
module Elasticsearch
2222
module API
2323
module Actions
24-
# Creates a new document in the index.
24+
# Create a new document in the index.
25+
# You can index a new JSON document with the +/<target>/_doc/+ or +/<target>/_create/<_id>+ APIs
26+
# Using +_create+ guarantees that the document is indexed only if it does not already exist.
27+
# It returns a 409 response when a document with a same ID already exists in the index.
28+
# To update an existing document, you must use the +/<target>/_doc/+ API.
29+
# If the Elasticsearch security features are enabled, you must have the following index privileges for the target data stream, index, or index alias:
30+
# * To add a document using the +PUT /<target>/_create/<_id>+ or +POST /<target>/_create/<_id>+ request formats, you must have the +create_doc+, +create+, +index+, or +write+ index privilege.
31+
# * To automatically create a data stream or index with this API request, you must have the +auto_configure+, +create_index+, or +manage+ index privilege.
32+
# Automatic data stream creation requires a matching index template with data stream enabled.
33+
# **Automatically create data streams and indices**
34+
# If the request's target doesn't exist and matches an index template with a +data_stream+ definition, the index operation automatically creates the data stream.
35+
# If the target doesn't exist and doesn't match a data stream template, the operation automatically creates the index and applies any matching index templates.
36+
# NOTE: Elasticsearch includes several built-in index templates. To avoid naming collisions with these templates, refer to index pattern documentation.
37+
# If no mapping exists, the index operation creates a dynamic mapping.
38+
# By default, new fields and objects are automatically added to the mapping if needed.
39+
# Automatic index creation is controlled by the +action.auto_create_index+ setting.
40+
# If it is +true+, any index can be created automatically.
41+
# You can modify this setting to explicitly allow or block automatic creation of indices that match specified patterns or set it to +false+ to turn off automatic index creation entirely.
42+
# Specify a comma-separated list of patterns you want to allow or prefix each pattern with +++ or +-+ to indicate whether it should be allowed or blocked.
43+
# When a list is specified, the default behaviour is to disallow.
44+
# NOTE: The +action.auto_create_index+ setting affects the automatic creation of indices only.
45+
# It does not affect the creation of data streams.
46+
# **Routing**
47+
# By default, shard placement — or routing — is controlled by using a hash of the document's ID value.
48+
# For more explicit control, the value fed into the hash function used by the router can be directly specified on a per-operation basis using the +routing+ parameter.
49+
# When setting up explicit mapping, you can also use the +_routing+ field to direct the index operation to extract the routing value from the document itself.
50+
# This does come at the (very minimal) cost of an additional document parsing pass.
51+
# If the +_routing+ mapping is defined and set to be required, the index operation will fail if no routing value is provided or extracted.
52+
# NOTE: Data streams do not support custom routing unless they were created with the +allow_custom_routing+ setting enabled in the template.
53+
# **Distributed**
54+
# The index operation is directed to the primary shard based on its route and performed on the actual node containing this shard.
55+
# After the primary shard completes the operation, if needed, the update is distributed to applicable replicas.
56+
# **Active shards**
57+
# To improve the resiliency of writes to the system, indexing operations can be configured to wait for a certain number of active shard copies before proceeding with the operation.
58+
# If the requisite number of active shard copies are not available, then the write operation must wait and retry, until either the requisite shard copies have started or a timeout occurs.
59+
# By default, write operations only wait for the primary shards to be active before proceeding (that is to say +wait_for_active_shards+ is +1+).
60+
# This default can be overridden in the index settings dynamically by setting +index.write.wait_for_active_shards+.
61+
# To alter this behavior per operation, use the +wait_for_active_shards request+ parameter.
62+
# Valid values are all or any positive integer up to the total number of configured copies per shard in the index (which is +number_of_replicas++1).
63+
# Specifying a negative value or a number greater than the number of shard copies will throw an error.
64+
# For example, suppose you have a cluster of three nodes, A, B, and C and you create an index index with the number of replicas set to 3 (resulting in 4 shard copies, one more copy than there are nodes).
65+
# If you attempt an indexing operation, by default the operation will only ensure the primary copy of each shard is available before proceeding.
66+
# This means that even if B and C went down and A hosted the primary shard copies, the indexing operation would still proceed with only one copy of the data.
67+
# If +wait_for_active_shards+ is set on the request to +3+ (and all three nodes are up), the indexing operation will require 3 active shard copies before proceeding.
68+
# This requirement should be met because there are 3 active nodes in the cluster, each one holding a copy of the shard.
69+
# However, if you set +wait_for_active_shards+ to +all+ (or to +4+, which is the same in this situation), the indexing operation will not proceed as you do not have all 4 copies of each shard active in the index.
70+
# The operation will timeout unless a new node is brought up in the cluster to host the fourth copy of the shard.
71+
# It is important to note that this setting greatly reduces the chances of the write operation not writing to the requisite number of shard copies, but it does not completely eliminate the possibility, because this check occurs before the write operation starts.
72+
# After the write operation is underway, it is still possible for replication to fail on any number of shard copies but still succeed on the primary.
73+
# The +_shards+ section of the API response reveals the number of shard copies on which replication succeeded and failed.
2574
#
26-
# Returns a 409 response when a document with a same ID already exists in the index.
27-
#
28-
# @option arguments [String] :id Document ID
29-
# @option arguments [String] :index The name of the index
30-
# @option arguments [String] :wait_for_active_shards Sets the number of shard copies that must be active before proceeding with the index operation. Defaults to 1, meaning the primary shard only. Set to `all` for all shard copies, otherwise set to any non-negative value less than or equal to the total number of copies for the shard (number of replicas + 1)
31-
# @option arguments [String] :refresh If `true` then refresh the affected shards to make this operation visible to search, if `wait_for` then wait for a refresh to make this operation visible to search, if `false` (the default) then do nothing with refreshes. (options: true, false, wait_for)
32-
# @option arguments [String] :routing Specific routing value
33-
# @option arguments [Time] :timeout Explicit operation timeout
34-
# @option arguments [Number] :version Explicit version number for concurrency control
35-
# @option arguments [String] :version_type Specific version type (options: internal, external, external_gte)
36-
# @option arguments [String] :pipeline The pipeline id to preprocess incoming documents with
37-
# @option arguments [Boolean] :include_source_on_error True or false if to include the document source in the error message in case of parsing errors. Defaults to true.
75+
# @option arguments [String] :id A unique identifier for the document.
76+
# To automatically generate a document ID, use the +POST /<target>/_doc/+ request format. (*Required*)
77+
# @option arguments [String] :index The name of the data stream or index to target.
78+
# If the target doesn't exist and matches the name or wildcard (+*+) pattern of an index template with a +data_stream+ definition, this request creates the data stream.
79+
# If the target doesn't exist and doesn’t match a data stream template, this request creates the index. (*Required*)
80+
# @option arguments [Integer] :if_primary_term Only perform the operation if the document has this primary term.
81+
# @option arguments [Integer] :if_seq_no Only perform the operation if the document has this sequence number.
82+
# @option arguments [Boolean] :include_source_on_error True or false if to include the document source in the error message in case of parsing errors. Server default: true.
83+
# @option arguments [String] :op_type Set to +create+ to only index the document if it does not already exist (put if absent).
84+
# If a document with the specified +_id+ already exists, the indexing operation will fail.
85+
# The behavior is the same as using the +<index>/_create+ endpoint.
86+
# If a document ID is specified, this paramater defaults to +index+.
87+
# Otherwise, it defaults to +create+.
88+
# If the request targets a data stream, an +op_type+ of +create+ is required.
89+
# @option arguments [String] :pipeline The ID of the pipeline to use to preprocess incoming documents.
90+
# If the index has a default ingest pipeline specified, setting the value to +_none+ turns off the default ingest pipeline for this request.
91+
# If a final pipeline is configured, it will always run regardless of the value of this parameter.
92+
# @option arguments [String] :refresh If +true+, Elasticsearch refreshes the affected shards to make this operation visible to search.
93+
# If +wait_for+, it waits for a refresh to make this operation visible to search.
94+
# If +false+, it does nothing with refreshes. Server default: false.
95+
# @option arguments [Boolean] :require_alias If +true+, the destination must be an index alias.
96+
# @option arguments [Boolean] :require_data_stream If +true+, the request's actions must target a data stream (existing or to be created).
97+
# @option arguments [String] :routing A custom value that is used to route operations to a specific shard.
98+
# @option arguments [Time] :timeout The period the request waits for the following operations: automatic index creation, dynamic mapping updates, waiting for active shards.
99+
# Elasticsearch waits for at least the specified timeout period before failing.
100+
# The actual wait time could be longer, particularly when multiple waits occur.This parameter is useful for situations where the primary shard assigned to perform the operation might not be available when the operation runs.
101+
# Some reasons for this might be that the primary shard is currently recovering from a gateway or undergoing relocation.
102+
# By default, the operation will wait on the primary shard to become available for at least 1 minute before failing and responding with an error.
103+
# The actual wait time could be longer, particularly when multiple waits occur. Server default: 1m.
104+
# @option arguments [Integer] :version The explicit version number for concurrency control.
105+
# It must be a non-negative long number.
106+
# @option arguments [String] :version_type The version type.
107+
# @option arguments [Integer, String] :wait_for_active_shards The number of shard copies that must be active before proceeding with the operation.
108+
# You can set it to +all+ or any positive integer up to the total number of shards in the index (+number_of_replicas+1+).
109+
# The default value of +1+ means it waits for each primary shard to be active. Server default: 1.
38110
# @option arguments [Hash] :headers Custom HTTP headers
39-
# @option arguments [Hash] :body The document (*Required*)
111+
# @option arguments [Hash] :body document
40112
#
41-
# @see https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-index_.html
113+
# @see https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-create
42114
#
43115
def create(arguments = {})
44116
request_opts = { endpoint: arguments[:endpoint] || 'create' }
45117

46-
defined_params = %i[index id].each_with_object({}) do |variable, set_variables|
118+
defined_params = [:index, :id].each_with_object({}) do |variable, set_variables|
47119
set_variables[variable] = arguments[variable] if arguments.key?(variable)
48120
end
49121
request_opts[:defined_params] = defined_params unless defined_params.empty?
50122

51-
if arguments[:id]
52-
index arguments.update op_type: 'create'
53-
else
54-
index arguments
55-
end
123+
raise ArgumentError, "Required argument 'body' missing" unless arguments[:body]
124+
raise ArgumentError, "Required argument 'index' missing" unless arguments[:index]
125+
raise ArgumentError, "Required argument 'id' missing" unless arguments[:id]
126+
127+
arguments = arguments.clone
128+
headers = arguments.delete(:headers) || {}
129+
130+
body = arguments.delete(:body)
131+
132+
_id = arguments.delete(:id)
133+
134+
_index = arguments.delete(:index)
135+
136+
method = Elasticsearch::API::HTTP_PUT
137+
path = "#{Utils.listify(_index)}/_create/#{Utils.listify(_id)}"
138+
params = Utils.process_params(arguments)
139+
140+
Elasticsearch::API::Response.new(
141+
perform_request(method, path, params, body, headers, request_opts)
142+
)
56143
end
57144
end
58145
end

elasticsearch-api/spec/unit/actions/create_document_spec.rb

Lines changed: 22 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -18,42 +18,40 @@
1818
require 'spec_helper'
1919

2020
describe 'client#create_document' do
21-
2221
let(:expected_args) do
2322
[
24-
'PUT',
25-
'foo/_doc/123',
26-
{ op_type: 'create' },
27-
{ foo: 'bar' },
28-
{},
29-
{ defined_params: { id: '123', index: 'foo' }, endpoint: 'index' }
23+
'PUT',
24+
'foo/_create/123',
25+
{},
26+
{ foo: 'bar' },
27+
{},
28+
{ defined_params: { id: '123', index: 'foo' }, endpoint: 'create' }
3029
]
3130
end
3231

3332
it 'performs the request' do
34-
expect(client_double.create(index: 'foo', id: '123', body: { foo: 'bar'})).to be_a Elasticsearch::API::Response
33+
expect(client_double.create(index: 'foo', id: '123', body: { foo: 'bar' })).to be_a Elasticsearch::API::Response
3534
end
3635

3736
context 'when the request needs to be URL-escaped' do
38-
3937
let(:expected_args) do
4038
[
41-
'PUT',
42-
'foo/_doc/123',
43-
{ op_type: 'create' },
44-
{},
45-
{}
39+
'PUT',
40+
'foo/_doc/123',
41+
{},
42+
{},
43+
{}
4644
]
4745
end
4846

4947
let(:expected_args) do
5048
[
5149
'PUT',
52-
'foo/_doc/123',
53-
{ op_type: 'create' },
50+
'foo/_create/123',
51+
{},
5452
{},
5553
{},
56-
{ defined_params: { id: '123', index: 'foo' }, endpoint: 'index' }
54+
{ defined_params: { id: '123', index: 'foo' }, endpoint: 'create' }
5755
]
5856
end
5957

@@ -63,58 +61,29 @@
6361
end
6462

6563
context 'when an id is provided as an integer' do
66-
67-
let(:expected_args) do
68-
[
69-
'PUT',
70-
'foo/_doc/1',
71-
{ op_type: 'create' },
72-
{ foo: 'bar' },
73-
{}
74-
]
75-
end
76-
7764
let(:expected_args) do
7865
[
7966
'PUT',
8067
'foo/_doc/1',
8168
{ op_type: 'create' },
8269
{ foo: 'bar' },
83-
{},
84-
{ defined_params: { id: 1, index: 'foo' }, endpoint: 'index' }
70+
{}
8571
]
8672
end
8773

88-
it 'updates the arguments with the `op_type`' do
89-
expect(client_double.create(index: 'foo', id: 1, body: { foo: 'bar' })).to be_a Elasticsearch::API::Response
90-
end
91-
end
92-
93-
context 'when an id is not provided' do
94-
9574
let(:expected_args) do
9675
[
97-
'POST',
98-
'foo/_doc',
99-
{ },
100-
{ foo: 'bar' },
101-
{}
102-
]
103-
end
104-
105-
let(:expected_args) do
106-
[
107-
'POST',
108-
'foo/_doc',
109-
{ },
76+
'PUT',
77+
'foo/_create/1',
78+
{},
11079
{ foo: 'bar' },
11180
{},
112-
{ defined_params: { index: 'foo' }, endpoint: 'index' }
81+
{ defined_params: { id: 1, index: 'foo' }, endpoint: 'create' }
11382
]
11483
end
11584

116-
it 'updates the arguments with the `op_type`' do
117-
expect(client_double.create(index: 'foo', body: { foo: 'bar' })).to be_a Elasticsearch::API::Response
85+
it 'performs the request' do
86+
expect(client_double.create(index: 'foo', id: 1, body: { foo: 'bar' })).to be_a Elasticsearch::API::Response
11887
end
11988
end
12089
end

0 commit comments

Comments
 (0)