diff --git a/README.md b/README.md index 4fc77dcf..493a815a 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,8 @@ Typesense use [HTTPlug](http://httplug.io/). List of clients & adapters [here](h | Typesense Server | typesense-php | |------------------|----------------| -| \>= v0.16.0 | \>= v4.2.0 | +| \>= v0.18.0 | \>= v4.4.0 | +| \>= v0.17.0 | \>= v4.2.0 | | \>= v0.16.0 | \>= v4.1.0 | | \>= v0.15.0 | \>= v4.0.0 | diff --git a/docker-compose.yml b/docker-compose.yml index 0cbfd56c..28e41e46 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,7 +2,7 @@ version: '3.5' services: typesense: - image: typesense/typesense:0.17.0 + image: typesense/typesense:0.18.0 environment: TYPESENSE_DATA_DIR: /data TYPESENSE_API_KEY: xyz diff --git a/examples/cluster_operations.php b/examples/cluster_operations.php new file mode 100644 index 00000000..98893507 --- /dev/null +++ b/examples/cluster_operations.php @@ -0,0 +1,29 @@ + 'xyz', + 'nodes' => [ + [ + 'host' => 'localhost', + 'port' => '8108', + 'protocol' => 'http', + ], + ], + 'client' => new HttplugClient(), + ] + ); + echo '
'; + + print_r($client->operations->perform('snapshot', ['snapshot_path' => '/tmp/snapshot'])); +} catch (Exception $e) { + echo $e->getMessage(); +} diff --git a/examples/synonym_operations.php b/examples/synonym_operations.php new file mode 100644 index 00000000..a883e8e5 --- /dev/null +++ b/examples/synonym_operations.php @@ -0,0 +1,150 @@ + 'xyz', + 'nodes' => [ + [ + 'host' => 'localhost', + 'port' => '8108', + 'protocol' => 'http', + ], + ], + 'client' => new HttplugClient(), + ] + ); + echo ''; + try { + print_r($client->collections['books']->delete()); + } catch (Exception $e) { + // Don't error out if the collection was not found + } + echo "--------Create Collection-------\n"; + print_r( + $client->collections->create( + [ + 'name' => 'books', + 'fields' => [ + [ + 'name' => 'title', + 'type' => 'string', + ], + [ + 'name' => 'authors', + 'type' => 'string[]', + 'facet' => true + ], + [ + 'name' => 'publication_year', + 'type' => 'int32', + 'facet' => true, + ], + [ + 'name' => 'ratings_count', + 'type' => 'int32', + ], + [ + 'name' => 'average_rating', + 'type' => 'float', + ], + [ + 'name' => 'image_url', + 'type' => 'string', + ], + ], + 'default_sorting_field' => 'ratings_count', + ] + ) + ); + echo "--------Create Collection-------\n"; + echo "\n"; + echo "--------Upsert Synonym-------\n"; + print_r( + $client->collections['books']->synonyms->upsert( + 'synonym-set-1', + [ + 'synonyms' => ['Hunger', 'Katniss'], + ] + ) + ); + echo "--------Upsert Synonym-------\n"; + echo "\n"; + echo "--------Get All Synonyms-------\n"; + print_r($client->collections['books']->synonyms->retrieve()); + echo "--------Get All Synonyms-------\n"; + echo "\n"; + echo "--------Get Single Synonym-------\n"; + print_r( + $client->collections['books']->synonyms['synonym-set-1']->retrieve() + ); + echo "--------Get Single Synonym-------\n"; + echo "\n"; + echo "--------Create Document-------\n"; + print_r( + $client->collections['books']->documents->create( + [ + 'id' => '1', + 'original_publication_year' => 2008, + 'authors' => [ + 'Suzanne Collins', + ], + 'average_rating' => 4.34, + 'publication_year' => 2008, + 'title' => 'The Hunger Games', + 'image_url' => 'https://images.gr-assets.com/books/1447303603m/2767052.jpg', + 'ratings_count' => 4780653, + ] + ) + ); + echo "--------Create Document-------\n"; + echo "\n"; + echo "--------Search Document, using a synonym-------\n"; + print_r( + $client->collections['books']->documents->search( + [ + 'q' => 'Katniss', + 'query_by' => 'title' + ] + ) + ); + echo "--------Search Document, using a synonym-------\n"; + echo "\n"; + echo "--------Upsert 1-way synonym-------\n"; + print_r( + $client->collections['books']->synonyms->upsert( + 'synonym-set-1', + [ + 'root' => 'Katniss', + 'synonyms' => ['Hunger', 'Peeta'], + ] + ) + ); + echo "--------Upsert 1-way synonym-------\n"; + echo "\n"; + echo "--------Search Document, using a synonym-------\n"; + // Won't return any results + print_r( + $client->collections['books']->documents->search( + [ + 'q' => 'Peeta', + 'query_by' => 'title' + ] + ) + ); + echo "--------Search Document, using a synonym-------\n"; + echo "\n"; + echo "--------Delete Synonym-------\n"; + print_r( + $client->collections['books']->getSynonyms()['synonym-set-1']->delete() + ); + echo "--------Delete Synonym-------\n"; + echo "\n"; +} catch (Exception $e) { + echo $e->getMessage(); +} diff --git a/src/ApiCall.php b/src/ApiCall.php index a60ccbf3..28465b3c 100644 --- a/src/ApiCall.php +++ b/src/ApiCall.php @@ -68,12 +68,12 @@ class ApiCall */ public function __construct(Configuration $config) { - $this->config = $config; - $this->logger = $config->getLogger(); - $this->client = $config->getClient(); + $this->config = $config; + $this->logger = $config->getLogger(); + $this->client = $config->getClient(); static::$nodes = $this->config->getNodes(); static::$nearestNode = $this->config->getNearestNode(); - $this->nodeIndex = 0; + $this->nodeIndex = 0; $this->initializeNodes(); } diff --git a/src/Client.php b/src/Client.php index 5ce2f194..8a17ea6d 100644 --- a/src/Client.php +++ b/src/Client.php @@ -50,6 +50,11 @@ class Client */ public Health $health; + /** + * @var Operations + */ + public Operations $operations; + /** * @var ApiCall */ @@ -73,6 +78,7 @@ public function __construct(array $config) $this->debug = new Debug($this->apiCall); $this->metrics = new Metrics($this->apiCall); $this->health = new Health($this->apiCall); + $this->operations = new Operations($this->apiCall); } /** @@ -122,4 +128,12 @@ public function getHealth(): Health { return $this->health; } + + /** + * @return Operations + */ + public function getOperations(): Operations + { + return $this->operations; + } } diff --git a/src/Collection.php b/src/Collection.php index fbd1f1d5..55cc76a9 100644 --- a/src/Collection.php +++ b/src/Collection.php @@ -35,6 +35,11 @@ class Collection */ public Overrides $overrides; + /** + * @var Synonyms + */ + public Synonyms $synonyms; + /** * Collection constructor. * @@ -47,6 +52,7 @@ public function __construct(string $name, ApiCall $apiCall) $this->apiCall = $apiCall; $this->documents = new Documents($name, $this->apiCall); $this->overrides = new Overrides($name, $this->apiCall); + $this->synonyms = new Synonyms($name, $this->apiCall); } /** @@ -73,6 +79,14 @@ public function getOverrides(): Overrides return $this->overrides; } + /** + * @return Synonyms + */ + public function getSynonyms(): Synonyms + { + return $this->synonyms; + } + /** * @return array * @throws TypesenseClientError|HttpClientException diff --git a/src/Operations.php b/src/Operations.php new file mode 100644 index 00000000..661c5974 --- /dev/null +++ b/src/Operations.php @@ -0,0 +1,48 @@ +apiCall = $apiCall; + } + + /** + * @param string $operationName + * @param array $queryParameters + * + * @return array + * @throws TypesenseClientError|HttpClientException + */ + public function perform(string $operationName, array $queryParameters = []): array + { + return $this->apiCall->post( + sprintf('%s/%s', static::RESOURCE_PATH, $operationName), + null, + true, + $queryParameters + ); + } +} diff --git a/src/Overrides.php b/src/Overrides.php index 0577ece8..3fb17099 100644 --- a/src/Overrides.php +++ b/src/Overrides.php @@ -61,15 +61,15 @@ public function endPointPath(string $overrideId = ''): string } /** - * @param string $documentId + * @param string $overrideId * @param array $config * * @return array * @throws TypesenseClientError|HttpClientException */ - public function upsert(string $documentId, array $config): array + public function upsert(string $overrideId, array $config): array { - return $this->apiCall->put($this->endPointPath($documentId), $config); + return $this->apiCall->put($this->endPointPath($overrideId), $config); } /** @@ -84,36 +84,36 @@ public function retrieve(): array /** * @inheritDoc */ - public function offsetExists($documentId): bool + public function offsetExists($overrideId): bool { - return isset($this->overrides[$documentId]); + return isset($this->overrides[$overrideId]); } /** * @inheritDoc */ - public function offsetGet($documentId) + public function offsetGet($overrideId) { - if (!isset($this->overrides[$documentId])) { - $this->overrides[$documentId] = new Override($this->collectionName, $documentId, $this->apiCall); + if (!isset($this->overrides[$overrideId])) { + $this->overrides[$overrideId] = new Override($this->collectionName, $overrideId, $this->apiCall); } - return $this->overrides[$documentId]; + return $this->overrides[$overrideId]; } /** * @inheritDoc */ - public function offsetSet($documentId, $value): void + public function offsetSet($overrideId, $value): void { - $this->overrides[$documentId] = $value; + $this->overrides[$overrideId] = $value; } /** * @inheritDoc */ - public function offsetUnset($documentId): void + public function offsetUnset($overrideId): void { - unset($this->overrides[$documentId]); + unset($this->overrides[$overrideId]); } } diff --git a/src/Synonym.php b/src/Synonym.php new file mode 100644 index 00000000..5ce46c15 --- /dev/null +++ b/src/Synonym.php @@ -0,0 +1,76 @@ +collectionName = $collectionName; + $this->synonymId = $synonymId; + $this->apiCall = $apiCall; + } + + /** + * @return string + */ + private function endPointPath(): string + { + return sprintf( + '%s/%s/%s/%s', + Collections::RESOURCE_PATH, + $this->collectionName, + synonyms::RESOURCE_PATH, + $this->synonymId + ); + } + + /** + * @return array + * @throws TypesenseClientError|HttpClientException + */ + public function retrieve(): array + { + return $this->apiCall->get($this->endPointPath(), []); + } + + /** + * @return array + * @throws TypesenseClientError|HttpClientException + */ + public function delete(): array + { + return $this->apiCall->delete($this->endPointPath()); + } +} diff --git a/src/Synonyms.php b/src/Synonyms.php new file mode 100644 index 00000000..62d97464 --- /dev/null +++ b/src/Synonyms.php @@ -0,0 +1,117 @@ +collectionName = $collectionName; + $this->apiCall = $apiCall; + } + + /** + * @param string $synonymId + * + * @return string + */ + public function endPointPath(string $synonymId = ''): string + { + return sprintf( + '%s/%s/%s/%s', + Collections::RESOURCE_PATH, + $this->collectionName, + static::RESOURCE_PATH, + $synonymId + ); + } + + /** + * @param string $synonymId + * @param array $config + * + * @return array + * @throws TypesenseClientError|HttpClientException + */ + public function upsert(string $synonymId, array $config): array + { + return $this->apiCall->put($this->endPointPath($synonymId), $config); + } + + /** + * @return array + * @throws TypesenseClientError|HttpClientException + */ + public function retrieve(): array + { + return $this->apiCall->get($this->endPointPath(), []); + } + + /** + * @inheritDoc + */ + public function offsetExists($synonymId): bool + { + return isset($this->synonyms[$synonymId]); + } + + /** + * @inheritDoc + */ + public function offsetGet($synonymId) + { + if (!isset($this->synonyms[$synonymId])) { + $this->synonyms[$synonymId] = new Synonym($this->collectionName, $synonymId, $this->apiCall); + } + + return $this->synonyms[$synonymId]; + } + + /** + * @inheritDoc + */ + public function offsetSet($synonymId, $value): void + { + $this->synonyms[$synonymId] = $value; + } + + /** + * @inheritDoc + */ + public function offsetUnset($synonymId): void + { + unset($this->synonyms[$synonymId]); + } +}