From c263181ddb4aa965a056d7c6329970a20889e86a Mon Sep 17 00:00:00 2001 From: Antoine Lamirault Date: Mon, 19 Aug 2019 09:00:43 +0200 Subject: [PATCH] Add request method parameter for search and count (#1441) (#1643) --- CHANGELOG.md | 2 + lib/Elastica/Index.php | 12 +++--- lib/Elastica/Search.php | 10 +++-- lib/Elastica/SearchableInterface.php | 8 ++-- lib/Elastica/Type.php | 12 +++--- lib/Elastica/Type/AbstractType.php | 13 +++--- test/Elastica/IndexTest.php | 48 +++++++++++++++++++++ test/Elastica/SearchTest.php | 58 +++++++++++++++++++++++++ test/Elastica/Transport/GuzzleTest.php | 54 ----------------------- test/Elastica/Transport/HttpTest.php | 59 -------------------------- test/Elastica/TypeTest.php | 40 +++++++++++++++++ 11 files changed, 181 insertions(+), 135 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f3c5a4f6e..ea0e3d8bc8 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ All notable changes to this project will be documented in this file based on the * hits.total is now an object in the search response [hits.total](https://www.elastic.co/guide/en/elasticsearch/reference/master/breaking-changes-7.0.html#_literal_hits_total_literal_is_now_an_object_in_the_search_response) * Elastica\Reindex does not return an Index anymore but a Response. * Elastica\Reindex->run() does not refresh the new Index after completion anymore. Use `$reindex->setParam(Reindex::REFRESH, 'wait_for')` instead. +* `Elastica\Search->search()` and `Elastica\Search->count()` use request method `POST` by default. Same for `Elastica\Index`, `Elastica\Type\AbstractType`, `Elastica\Type`. ### Bugfixes * Always set the Guzzle `base_uri` to support connecting to multiple ES hosts. [#1618](https://github.com/ruflin/Elastica/pull/1618) @@ -26,6 +27,7 @@ All notable changes to this project will be documented in this file based on the * Added `ParentAggregation` [#1616](https://github.com/ruflin/Elastica/pull/1616) * Elastica\Reindex missing options (script, remote, wait_for_completion, scroll...) * Added `AdjacencyMatrix` aggregation [#1642](https://github.com/ruflin/Elastica/pull/1642) +* Added request method parameter to `Elastica\SearchableInterface->search()` and `Elastica\SearchableInterface->count()`. Same for `Elastica\Search`[#1441](https://github.com/ruflin/Elastica/issues/1441) ### Improvements * Added `native_function_invocation` CS rule [#1606](https://github.com/ruflin/Elastica/pull/1606) diff --git a/lib/Elastica/Index.php b/lib/Elastica/Index.php index 29eb0b2ed2..edda01e4f4 100644 --- a/lib/Elastica/Index.php +++ b/lib/Elastica/Index.php @@ -353,32 +353,34 @@ public function createSearch($query = '', $options = null, BuilderInterface $bui * * @param string|array|\Elastica\Query $query Array with all query data inside or a Elastica\Query object * @param int|array $options OPTIONAL Limit or associative array of options (option=>value) + * @param string $method OPTIONAL Request method (use const's) (default = Request::POST) * * @return \Elastica\ResultSet with all results inside * * @see \Elastica\SearchableInterface::search */ - public function search($query = '', $options = null) + public function search($query = '', $options = null, $method = Request::POST) { $search = $this->createSearch($query, $options); - return $search->search(); + return $search->search('', null, $method); } /** * Counts results of query. * - * @param string|array|\Elastica\Query $query Array with all query data inside or a Elastica\Query object + * @param string|array|\Elastica\Query $query Array with all query data inside or a Elastica\Query object + * @param string $method OPTIONAL Request method (use const's) (default = Request::POST) * * @return int number of documents matching the query * * @see \Elastica\SearchableInterface::count */ - public function count($query = '') + public function count($query = '', $method = Request::POST) { $search = $this->createSearch($query); - return $search->count(); + return $search->count('', false, $method); } /** diff --git a/lib/Elastica/Search.php b/lib/Elastica/Search.php index b524d887ca..1b113e8db5 100644 --- a/lib/Elastica/Search.php +++ b/lib/Elastica/Search.php @@ -436,12 +436,13 @@ public function getPath() * * @param mixed $query * @param int|array $options OPTIONAL Limit or associative array of options (option=>value) + * @param string $method OPTIONAL Request method (use const's) (default = Request::POST) * * @throws \Elastica\Exception\InvalidException * * @return \Elastica\ResultSet */ - public function search($query = '', $options = null) + public function search($query = '', $options = null, $method = Request::POST) { $this->setOptionsAndQuery($options, $query); @@ -460,7 +461,7 @@ public function search($query = '', $options = null) $response = $this->getClient()->request( $path, - Request::GET, + $method, $data, $params ); @@ -471,10 +472,11 @@ public function search($query = '', $options = null) /** * @param mixed $query * @param $fullResult (default = false) By default only the total hit count is returned. If set to true, the full ResultSet including aggregations is returned + * @param string $method OPTIONAL Request method (use const's) (default = Request::POST) * * @return int|ResultSet */ - public function count($query = '', $fullResult = false) + public function count($query = '', $fullResult = false, $method = Request::POST) { $this->setOptionsAndQuery(null, $query); @@ -485,7 +487,7 @@ public function count($query = '', $fullResult = false) $response = $this->getClient()->request( $path, - Request::GET, + $method, $query->toArray(), [self::OPTION_SEARCH_TYPE => self::OPTION_SEARCH_TYPE_QUERY_THEN_FETCH] ); diff --git a/lib/Elastica/SearchableInterface.php b/lib/Elastica/SearchableInterface.php index 1fb4bdfb28..94adb61fd1 100644 --- a/lib/Elastica/SearchableInterface.php +++ b/lib/Elastica/SearchableInterface.php @@ -27,21 +27,23 @@ interface SearchableInterface * * @param string|array|\Elastica\Query $query Array with all query data inside or a Elastica\Query object * @param null $options + * @param string $method OPTIONAL Request method (use const's) (default = Request::POST) * * @return \Elastica\ResultSet with all results inside */ - public function search($query = '', $options = null); + public function search($query = '', $options = null, $method = Request::POST); /** * Counts results for a query. * * If no query is set, matchall query is created * - * @param string|array|\Elastica\Query $query Array with all query data inside or a Elastica\Query object + * @param string|array|\Elastica\Query $query Array with all query data inside or a Elastica\Query object + * @param string $method OPTIONAL Request method (use const's) (default = Request::POST) * * @return int number of documents matching the query */ - public function count($query = ''); + public function count($query = '', $method = Request::POST); /** * @param \Elastica\Query|string $query diff --git a/lib/Elastica/Type.php b/lib/Elastica/Type.php index de5dbafe5f..be470c8e59 100644 --- a/lib/Elastica/Type.php +++ b/lib/Elastica/Type.php @@ -349,32 +349,34 @@ public function createSearch($query = '', $options = null, BuilderInterface $bui * * @param string|array|\Elastica\Query $query Array with all query data inside or a Elastica\Query object * @param int|array $options OPTIONAL Limit or associative array of options (option=>value) + * @param string $method OPTIONAL Request method (use const's) (default = Request::POST) * * @return \Elastica\ResultSet with all results inside * * @see \Elastica\SearchableInterface::search */ - public function search($query = '', $options = null) + public function search($query = '', $options = null, $method = Request::POST) { $search = $this->createSearch($query, $options); - return $search->search(); + return $search->search('', null, $method); } /** * Count docs by query. * - * @param string|array|\Elastica\Query $query Array with all query data inside or a Elastica\Query object + * @param string|array|\Elastica\Query $query Array with all query data inside or a Elastica\Query object + * @param string $method OPTIONAL Request method (use const's) (default = Request::POST) * * @return int number of documents matching the query * * @see \Elastica\SearchableInterface::count */ - public function count($query = '') + public function count($query = '', $method = Request::POST) { $search = $this->createSearch($query); - return $search->count(); + return $search->count('', false, $method); } /** diff --git a/lib/Elastica/Type/AbstractType.php b/lib/Elastica/Type/AbstractType.php index b775e4cf8a..00118fd9a1 100644 --- a/lib/Elastica/Type/AbstractType.php +++ b/lib/Elastica/Type/AbstractType.php @@ -6,6 +6,7 @@ use Elastica\Exception\InvalidException; use Elastica\Index; use Elastica\Query; +use Elastica\Request; use Elastica\ResultSet; use Elastica\Search; use Elastica\SearchableInterface; @@ -151,28 +152,30 @@ public function createSearch($query = '', $options = null): Search * * @param string|array|Query $query Array with all query data inside or a Elastica\Query object * @param int|array $options + * @param string $method OPTIONAL Request method (use const's) (default = Request::POST) * * @return ResultSet with all results inside * * @see \Elastica\SearchableInterface::search */ - public function search($query = '', $options = null): ResultSet + public function search($query = '', $options = null, $method = Request::POST): ResultSet { - return $this->getType()->search($query, $options = null); + return $this->getType()->search($query, $options = null, $method); } /** * Count docs in the type based on query. * - * @param string|array|Query $query Array with all query data inside or a Elastica\Query object + * @param string|array|Query $query Array with all query data inside or a Elastica\Query object + * @param string $method OPTIONAL Request method (use const's) (default = Request::POST) * * @return int number of documents matching the query * * @see \Elastica\SearchableInterface::count */ - public function count($query = ''): int + public function count($query = '', $method = Request::POST): int { - return $this->getType()->count($query); + return $this->getType()->count($query, $method); } /** diff --git a/test/Elastica/IndexTest.php b/test/Elastica/IndexTest.php index ea35670347..855b204f7d 100644 --- a/test/Elastica/IndexTest.php +++ b/test/Elastica/IndexTest.php @@ -140,6 +140,33 @@ public function testCount() $this->assertEquals(1, $index->count($query)); } + /** + * @group functional + */ + public function testCountGet() + { + $index = $this->_createIndex(); + + // Add document to normal index + $doc1 = new Document(null, ['name' => 'ruflin']); + $doc2 = new Document(null, ['name' => 'nicolas']); + + $type = $index->getType('_doc'); + $type->addDocument($doc1); + $type->addDocument($doc2); + + $index->refresh(); + + $this->assertEquals(2, $index->count('', Request::GET)); + + $query = new Term(); + $key = 'name'; + $value = 'nicolas'; + $query->setTerm($key, $value); + + $this->assertEquals(1, $index->count($query, Request::GET)); + } + /** * @group functional */ @@ -696,6 +723,27 @@ public function testSearch() $this->assertEquals(3, $count); } + /** + * @group functional + */ + public function testSearchGet() + { + $index = $this->_createIndex(); + + $type = new Type($index, '_doc'); + + $docs = []; + $docs[] = new Document(1, ['username' => 'hans']); + $type->addDocuments($docs); + $index->refresh(); + + $resultSet = $index->search('hans', null, Request::GET); + $this->assertEquals(1, $resultSet->count()); + + $count = $index->count('hans', Request::GET); + $this->assertEquals(1, $count); + } + /** * @group functional */ diff --git a/test/Elastica/SearchTest.php b/test/Elastica/SearchTest.php index 5ca918e1f0..99c58363e1 100644 --- a/test/Elastica/SearchTest.php +++ b/test/Elastica/SearchTest.php @@ -10,6 +10,7 @@ use Elastica\Query\FunctionScore; use Elastica\Query\MatchAll; use Elastica\Query\QueryString; +use Elastica\Request; use Elastica\Response; use Elastica\ResultSet; use Elastica\Script\Script; @@ -456,6 +457,18 @@ public function testSearchWithVersionOption() $this->assertEquals(1, $hit->getParam('_version')); } + /** + * @group functional + */ + public function testSearchGet() + { + $client = $this->_getClient(); + $search1 = new Search($client); + + $result = $search1->search([], [], 'GET'); + $this->assertFalse($result->getResponse()->hasError()); + } + /** * @group functional */ @@ -501,6 +514,51 @@ public function testCountRequest() $this->assertEquals(0, $count); } + /** + * @group functional + */ + public function testCountRequestGet() + { + $client = $this->_getClient(); + $search = new Search($client); + + $index = $client->getIndex('zero'); + $index->create(['settings' => ['index' => ['number_of_shards' => 1, 'number_of_replicas' => 0]]], true); + + $type = $index->getType('_doc'); + $type->addDocuments([ + new Document(1, ['id' => 1, 'email' => 'test@test.com', 'username' => 'farrelley']), + new Document(2, ['id' => 1, 'email' => 'test@test.com', 'username' => 'farrelley']), + new Document(3, ['id' => 1, 'email' => 'test@test.com', 'username' => 'farrelley']), + new Document(4, ['id' => 1, 'email' => 'test@test.com', 'username' => 'farrelley']), + new Document(5, ['id' => 1, 'email' => 'test@test.com', 'username' => 'farrelley']), + new Document(6, ['id' => 1, 'email' => 'test@test.com', 'username' => 'marley']), + new Document(7, ['id' => 1, 'email' => 'test@test.com', 'username' => 'marley']), + new Document(8, ['id' => 1, 'email' => 'test@test.com', 'username' => 'marley']), + new Document(9, ['id' => 1, 'email' => 'test@test.com', 'username' => 'marley']), + new Document(10, ['id' => 1, 'email' => 'test@test.com', 'username' => 'marley']), + new Document(11, ['id' => 1, 'email' => 'test@test.com', 'username' => 'marley']), + ]); + $index->refresh(); + + $search->addIndex($index)->addType($type); + + $count = $search->count('farrelley', false, Request::GET); + $this->assertEquals(5, $count); + + $count = $search->count('marley', false, Request::GET); + $this->assertEquals(6, $count); + + $count = $search->count('', false, Request::GET); + $this->assertEquals(6, $count, 'Uses previous query set'); + + $count = $search->count(new MatchAll(), false, Request::GET); + $this->assertEquals(11, $count); + + $count = $search->count('bunny', false, Request::GET); + $this->assertEquals(0, $count); + } + /** * @group functional */ diff --git a/test/Elastica/Transport/GuzzleTest.php b/test/Elastica/Transport/GuzzleTest.php index 7f28186b0b..4f4b4f2fc0 100644 --- a/test/Elastica/Transport/GuzzleTest.php +++ b/test/Elastica/Transport/GuzzleTest.php @@ -16,60 +16,6 @@ public static function setUpBeforeClass() } } - /** - * Return transport configuration and the expected HTTP method. - * - * @return array[] - */ - public function getConfig() - { - return [ - [ - ['persistent' => false, 'transport' => 'Guzzle'], - 'GET', - ], - [ - ['persistent' => false, 'transport' => ['type' => 'Guzzle', 'postWithRequestBody' => false]], - 'GET', - ], - [ - ['persistent' => false, 'transport' => ['type' => 'Guzzle', 'postWithRequestBody' => true]], - 'POST', - ], - ]; - } - - /** - * @group functional - * @dataProvider getConfig - */ - public function testDynamicHttpMethodBasedOnConfigParameter(array $config, $httpMethod) - { - $client = $this->_getClient($config); - - $index = $client->getIndex('dynamic_http_method_test'); - $index->create([], true); - $type = $index->getType('_doc'); - $type->addDocument(new Document(1, ['test' => 'test'])); - $index->refresh(); - $resultSet = $index->search('test'); - $info = $resultSet->getResponse()->getTransferInfo(); - $this->assertStringStartsWith($httpMethod, $info['request_header']); - } - - /** - * @group functional - * @dataProvider getConfig - */ - public function testDynamicHttpMethodOnlyAffectsRequestsWithBody(array $config, $httpMethod) - { - $client = $this->_getClient($config); - - $status = $client->getStatus(); - $info = $status->getResponse()->getTransferInfo(); - $this->assertStringStartsWith('GET', $info['request_header']); - } - /** * @group functional */ diff --git a/test/Elastica/Transport/HttpTest.php b/test/Elastica/Transport/HttpTest.php index da41d59653..daf033dfa7 100644 --- a/test/Elastica/Transport/HttpTest.php +++ b/test/Elastica/Transport/HttpTest.php @@ -9,65 +9,6 @@ class HttpTest extends BaseTest { - /** - * Return transport configuration and the expected HTTP method. - * - * @return array[] - */ - public function getConfig() - { - return [ - [ - ['transport' => 'Http', 'curl' => [CURLINFO_HEADER_OUT => true]], - 'GET', - ], - [ - ['transport' => ['type' => 'Http', 'postWithRequestBody' => false, 'curl' => [CURLINFO_HEADER_OUT => true]]], - 'GET', - ], - [ - ['transport' => ['type' => 'Http', 'postWithRequestBody' => true, 'curl' => [CURLINFO_HEADER_OUT => true]]], - 'POST', - ], - ]; - } - - /** - * @group functional - * @dataProvider getConfig - */ - public function testDynamicHttpMethodBasedOnConfigParameter(array $config, $httpMethod) - { - $client = $this->_getClient($config); - - $index = $client->getIndex('dynamic_http_method_test'); - $index->create([], true); - $this->_waitForAllocation($index); - - $type = $index->getType('_doc'); - $type->addDocument(new Document(1, ['test' => 'test'])); - - $index->refresh(); - - $resultSet = $index->search('test'); - - $info = $resultSet->getResponse()->getTransferInfo(); - $this->assertStringStartsWith($httpMethod, $info['request_header']); - } - - /** - * @group functional - * @dataProvider getConfig - */ - public function testDynamicHttpMethodOnlyAffectsRequestsWithBody(array $config, $httpMethod) - { - $client = $this->_getClient($config); - - $status = $client->getStatus(); - $info = $status->getResponse()->getTransferInfo(); - $this->assertStringStartsWith('GET', $info['request_header']); - } - /** * @group functional */ diff --git a/test/Elastica/TypeTest.php b/test/Elastica/TypeTest.php index b966cb2456..1942c018aa 100644 --- a/test/Elastica/TypeTest.php +++ b/test/Elastica/TypeTest.php @@ -9,6 +9,7 @@ use Elastica\Query\MatchAll; use Elastica\Query\QueryString; use Elastica\Query\SimpleQueryString; +use Elastica\Request; use Elastica\Script\Script; use Elastica\Search; use Elastica\Test\Base as BaseTest; @@ -57,6 +58,45 @@ public function testSearch() $this->assertEquals('rolf', $data['username']); } + /** + * @group functional + */ + public function testSearchGet() + { + $index = $this->_createIndex(); + + $type = new Type($index, '_doc'); + + // Adds 1 document to the index + $doc1 = new Document(1, + ['username' => 'hans', 'test' => ['2', '3', '5']] + ); + $type->addDocument($doc1); + + // Adds a list of documents with _bulk upload to the index + $docs = []; + $docs[] = new Document(2, + ['username' => 'john', 'test' => ['1', '3', '6']] + ); + $docs[] = new Document(3, + ['username' => 'rolf', 'test' => ['2', '3', '7']] + ); + $type->addDocuments($docs); + $index->refresh(); + + $resultSet = $type->search('rolf', null, Request::GET); + $this->assertEquals(1, $resultSet->count()); + + $count = $type->count('rolf', Request::GET); + $this->assertEquals(1, $count); + + // Test if source is returned + $result = $resultSet->current(); + $this->assertEquals(3, $result->getId()); + $data = $result->getData(); + $this->assertEquals('rolf', $data['username']); + } + /** * @group functional */