Skip to content

Commit 1d169b6

Browse files
mmoreramruflin
authored andcommitted
Added updateByQuery endpoint (#1499)
1 parent 1b098c3 commit 1d169b6

File tree

3 files changed

+99
-0
lines changed

3 files changed

+99
-0
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ All notable changes to this project will be documented in this file based on the
1313
* Added support for pipeline when indexing document. [#1455](https://github.com/ruflin/Elastica/pull/1455)
1414
* Added support for multiple bucket sort orders for aggregations. [#1480](https://github.com/ruflin/Elastica/pull/1480)
1515
* Added basic support for the Elasticsearch Task Api
16+
* Added updateByQuery endpoint. [#1499](https://github.com/ruflin/Elastica/pull/1499)
1617

1718
### Improvements
1819

lib/Elastica/Index.php

+29
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use Elastica\Index\Settings as IndexSettings;
77
use Elastica\Index\Stats as IndexStats;
88
use Elastica\ResultSet\BuilderInterface;
9+
use Elastica\Script\AbstractScript;
910
use Elasticsearch\Endpoints\AbstractEndpoint;
1011
use Elasticsearch\Endpoints\DeleteByQuery;
1112
use Elasticsearch\Endpoints\Indices\Aliases\Update;
@@ -21,6 +22,7 @@
2122
use Elasticsearch\Endpoints\Indices\Open;
2223
use Elasticsearch\Endpoints\Indices\Refresh;
2324
use Elasticsearch\Endpoints\Indices\Settings\Put;
25+
use Elasticsearch\Endpoints\UpdateByQuery;
2426

2527
/**
2628
* Elastica index object.
@@ -134,6 +136,33 @@ public function updateDocuments(array $docs, array $options = [])
134136
return $this->getClient()->updateDocuments($docs, $options);
135137
}
136138

139+
/**
140+
* Update entries in the db based on a query.
141+
*
142+
* @param \Elastica\Query|string|array $query Query object or array
143+
* @param AbstractScript $script Script
144+
* @param array $options Optional params
145+
*
146+
* @return \Elastica\Response
147+
*
148+
* @link https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-update-by-query.html
149+
*/
150+
public function updateByQuery($query, AbstractScript $script , array $options = [])
151+
{
152+
$query = Query::create($query)->getQuery();
153+
154+
$endpoint = new UpdateByQuery();
155+
$body = ['query' => is_array($query)
156+
? $query
157+
: $query->toArray()];
158+
159+
$body['script'] = $script->toArray()['script'];
160+
$endpoint->setBody($body);
161+
$endpoint->setParams($options);
162+
163+
return $this->requestEndpoint($endpoint);
164+
}
165+
137166
/**
138167
* Uses _bulk to send documents to the server.
139168
*

test/Elastica/IndexTest.php

+69
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use Elastica\Query\SimpleQueryString;
99
use Elastica\Query\Term;
1010
use Elastica\Request;
11+
use Elastica\Script\Script;
1112
use Elastica\Status;
1213
use Elastica\Test\Base as BaseTest;
1314
use Elastica\Type;
@@ -290,6 +291,74 @@ public function testDeleteByQueryWithQueryAndOptions()
290291
$this->assertEquals(0, $response->count());
291292
}
292293

294+
/**
295+
* @group functional
296+
*/
297+
public function testUpdateByQueryWithQueryString()
298+
{
299+
$index = $this->_createIndex();
300+
$type1 = new Type($index, 'test1');
301+
$type1->addDocument(new Document(1, ['name' => 'ruflin nicolas']));
302+
$type1->addDocument(new Document(2, ['name' => 'ruflin']));
303+
$index->refresh();
304+
305+
$response = $index->search('ruflin*');
306+
$this->assertEquals(2, $response->count());
307+
308+
$response = $index->search('nicolas');
309+
$this->assertEquals(1, $response->count());
310+
311+
// Update the element, searched by specific word. Should match first one
312+
$response = $index->updateByQuery('nicolas', new Script('ctx._source.name = "marc"'));
313+
$this->assertTrue($response->isOk());
314+
315+
$index->refresh();
316+
317+
// Makes sure first element is updated and renamed to marc. Should match only second
318+
$response = $index->search('ruflin*');
319+
$this->assertEquals(1, $response->count());
320+
321+
$response = $index->search('marc*');
322+
$this->assertEquals(1, $response->count());
323+
324+
$response = $index->search('nicolas');
325+
$this->assertEquals(0, $response->count());
326+
}
327+
328+
/**
329+
* @group functional
330+
*/
331+
public function testUpdateByQueryAll()
332+
{
333+
$index = $this->_createIndex();
334+
$type1 = new Type($index, 'test1');
335+
$type1->addDocument(new Document(1, ['name' => 'ruflin nicolas']));
336+
$type1->addDocument(new Document(2, ['name' => 'ruflin']));
337+
$index->refresh();
338+
339+
$response = $index->search('ruflin*');
340+
$this->assertEquals(2, $response->count());
341+
342+
$response = $index->search('nicolas');
343+
$this->assertEquals(1, $response->count());
344+
345+
// Update all elements to name "marc"
346+
$response = $index->updateByQuery('*', new Script('ctx._source.name = "marc"'));
347+
$this->assertTrue($response->isOk());
348+
349+
$index->refresh();
350+
351+
// Because all documents have changed to marc, searching by "ruflin*" should match 0
352+
$response = $index->search('ruflin*');
353+
$this->assertEquals(0, $response->count());
354+
355+
$response = $index->search('marc');
356+
$this->assertEquals(2, $response->count());
357+
358+
$response = $index->search('nicolas');
359+
$this->assertEquals(0, $response->count());
360+
}
361+
293362
/**
294363
* @group functional
295364
*/

0 commit comments

Comments
 (0)