1[[indexing_documents]]
2=== Indexing documents
3
4IMPORTANT: Please note that mapping types will disappear from {es}, read more
5{ref-7x}/removal-of-types.html[here]. If you migrated types from {es} 6 to 7,
6you can address these with the `type` param.
7
8When you add documents to {es}, you index JSON documents. This maps naturally to
9PHP associative arrays, since they can easily be encoded in JSON. Therefore, in
10Elasticsearch-PHP you create and pass associative arrays to the client for
11indexing. There are several methods of ingesting data into {es} which we cover
12here.
13
14[discrete]
15==== Single document indexing
16
17When indexing a document, you can either provide an ID or let {es} generate one
18for you.
19
20{zwsp} +
21
22.Providing an ID value
23[source,php]
24----
25$params = [
26    'index' => 'my_index',
27    'id'    => 'my_id',
28    'body'  => [ 'testField' => 'abc']
29];
30
31// Document will be indexed to my_index/_doc/my_id
32$response = $client->index($params);
33----
34{zwsp} +
35
36.Omitting an ID value
37[source,php]
38----
39$params = [
40    'index' => 'my_index',
41    'body'  => [ 'testField' => 'abc']
42];
43
44// Document will be indexed to my_index/_doc/<autogenerated ID>
45$response = $client->index($params);
46----
47{zwsp} +
48
49If you need to set other parameters, such as a `routing` value, you specify
50those in the array alongside the `index`, and others. For example, let's set the
51routing and timestamp of this new document:
52
53.Additional parameters
54[source,php]
55----
56$params = [
57    'index'     => 'my_index',
58    'id'        => 'my_id',
59    'routing'   => 'company_xyz',
60    'timestamp' => strtotime("-1d"),
61    'body'      => [ 'testField' => 'abc']
62];
63
64
65$response = $client->index($params);
66----
67{zwsp} +
68
69[discrete]
70==== Bulk Indexing
71
72{es} also supports bulk indexing of documents. The bulk API expects JSON
73action/metadata pairs, separated by newlines. When constructing your documents
74in PHP, the process is similar. You first create an action array object (for
75example, an `index` object), then you create a document body object. This
76process repeats for all your documents.
77
78A simple example might look like this:
79
80.Bulk indexing with PHP arrays
81[source,php]
82----
83for($i = 0; $i < 100; $i++) {
84    $params['body'][] = [
85        'index' => [
86            '_index' => 'my_index',
87	    ]
88    ];
89
90    $params['body'][] = [
91        'my_field'     => 'my_value',
92        'second_field' => 'some more values'
93    ];
94}
95
96$responses = $client->bulk($params);
97----
98
99In practice, you'll likely have more documents than you want to send in a single
100bulk request. In that case, you need to batch up the requests and periodically
101send them:
102
103.Bulk indexing with batches
104[source,php]
105----
106$params = ['body' => []];
107
108for ($i = 1; $i <= 1234567; $i++) {
109    $params['body'][] = [
110        'index' => [
111            '_index' => 'my_index',
112            '_id'    => $i
113        ]
114    ];
115
116    $params['body'][] = [
117        'my_field'     => 'my_value',
118        'second_field' => 'some more values'
119    ];
120
121    // Every 1000 documents stop and send the bulk request
122    if ($i % 1000 == 0) {
123        $responses = $client->bulk($params);
124
125        // erase the old bulk request
126        $params = ['body' => []];
127
128        // unset the bulk response when you are done to save memory
129        unset($responses);
130    }
131}
132
133// Send the last batch if it exists
134if (!empty($params['body'])) {
135    $responses = $client->bulk($params);
136}
137----
138
139[[getting_documents]]
140=== Getting documents
141
142{es} provides realtime GETs of documents. This means that as soon as the
143document is indexed and your client receives an acknowledgement, you can
144immediately retrieve the document from any shard. Get operations are performed
145by requesting a document by its full `index/type/id` path:
146
147[source,php]
148----
149$params = [
150    'index' => 'my_index',
151    'id'    => 'my_id'
152];
153
154// Get doc at /my_index/_doc/my_id
155$response = $client->get($params);
156----
157{zwsp} +
158
159[[updating_documents]]
160=== Updating documents
161
162Updating a document allows you to either completely replace the contents of the
163existing document, or perform a partial update to just some fields (either
164changing an existing field or adding new fields).
165
166[discrete]
167==== Partial document update
168
169If you want to partially update a document (for example, change an existing
170field or add a new one) you can do so by specifying the `doc` in the `body`
171parameter. This merges the fields in `doc` with the existing document.
172
173
174[source,php]
175----
176$params = [
177    'index' => 'my_index',
178    'id'    => 'my_id',
179    'body'  => [
180        'doc' => [
181            'new_field' => 'abc'
182        ]
183    ]
184];
185
186// Update doc at /my_index/_doc/my_id
187$response = $client->update($params);
188----
189{zwsp} +
190
191[discrete]
192==== Scripted document update
193
194Sometimes you need to perform a scripted update, such as incrementing a counter
195or appending a new value to an array. To perform a scripted update, you need to
196provide a script and usually a set of parameters:
197
198[source,php]
199----
200$params = [
201    'index' => 'my_index',
202    'id'    => 'my_id',
203    'body'  => [
204        'script' => 'ctx._source.counter += count',
205        'params' => [
206            'count' => 4
207        ]
208    ]
209];
210
211$response = $client->update($params);
212----
213{zwsp} +
214
215[discrete]
216==== Upserts
217
218Upserts are "Update or Insert" operations. This means an upsert attempts to run
219your update script, but if the document does not exist (or the field you are
220trying to update doesn't exist), default values are inserted instead.
221
222[source,php]
223----
224$params = [
225    'index' => 'my_index',
226    'id'    => 'my_id',
227    'body'  => [
228        'script' => [
229            'source' => 'ctx._source.counter += params.count',
230            'params' => [
231                'count' => 4
232            ],
233        ],
234        'upsert' => [
235            'counter' => 1
236        ],
237    ]
238];
239
240$response = $client->update($params);
241----
242{zwsp} +
243
244
245[[deleting_documents]]
246=== Deleting documents
247
248Finally, you can delete documents by specifying their full `/index/_doc_/id`
249path:
250
251[source,php]
252----
253$params = [
254    'index' => 'my_index',
255    'id'    => 'my_id'
256];
257
258// Delete doc at /my_index/_doc_/my_id
259$response = $client->delete($params);
260----
261{zwsp} +
262