Skip to content

Commit decc2cf

Browse files
committed
feat: support synonym endpoint
1 parent fe9cf5c commit decc2cf

3 files changed

Lines changed: 212 additions & 0 deletions

File tree

src/Objects/Synonym.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Typesense\Objects;
6+
7+
class Synonym extends TypesenseObject
8+
{
9+
public string $id;
10+
11+
/**
12+
* @var array<int, string>
13+
*/
14+
public array $synonyms;
15+
16+
public string $root = '';
17+
18+
public string $locale = '';
19+
20+
/**
21+
* @var array<int, string>
22+
*/
23+
public array $symbols_to_index = [];
24+
}

src/Requests/Synonym.php

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Typesense\Requests;
6+
7+
use stdClass;
8+
use Typesense\Exceptions\Client\ResourceNotFoundException;
9+
use Typesense\Objects\Synonym as SynonymObject;
10+
11+
class Synonym extends Request
12+
{
13+
/**
14+
* Create or update a synonym.
15+
*
16+
* @param array{
17+
* synonyms: array<int, string>,
18+
* root?: string,
19+
* locale?: string,
20+
* symbols_to_index?: array<int, string>,
21+
* } $payload
22+
*
23+
* @see https://typesense.org/docs/latest/api/synonyms.html#create-or-update-a-synonym
24+
*/
25+
public function upsert(string $collection, string $id, array $payload): SynonymObject
26+
{
27+
$path = sprintf('/collections/%s/synonyms/%s', $collection, $id);
28+
29+
$data = $this->send('PUT', $path, $payload);
30+
31+
return SynonymObject::from($data);
32+
}
33+
34+
/**
35+
* Retrieve a single synonym.
36+
*
37+
* @throws ResourceNotFoundException
38+
*
39+
* @see https://typesense.org/docs/latest/api/synonyms.html#retrieve-a-synonym
40+
*/
41+
public function retrieve(string $collection, string $id): SynonymObject
42+
{
43+
$path = sprintf('/collections/%s/synonyms/%s', $collection, $id);
44+
45+
$data = $this->send('GET', $path);
46+
47+
return SynonymObject::from($data);
48+
}
49+
50+
/**
51+
* List all synonyms associated with a given collection.
52+
*
53+
* @return array<int, SynonymObject>
54+
*
55+
* @see https://typesense.org/docs/latest/api/synonyms.html#list-all-synonyms
56+
*/
57+
public function list(string $collection): array
58+
{
59+
$path = sprintf('/collections/%s/synonyms', $collection);
60+
61+
$data = $this->send('GET', $path);
62+
63+
return array_map(
64+
fn (stdClass $datum) => SynonymObject::from($datum),
65+
$data->aliases,
66+
);
67+
}
68+
69+
/**
70+
* Delete a synonym associated with a collection.
71+
*
72+
* @throws ResourceNotFoundException
73+
*
74+
* @see https://typesense.org/docs/latest/api/synonyms.html#delete-a-synonym
75+
*/
76+
public function delete(string $collection, string $id): bool
77+
{
78+
$path = sprintf('/collections/%s/synonyms/%s', $collection, $id);
79+
80+
$data = $this->send('DELETE', $path);
81+
82+
return $data->id === $id;
83+
}
84+
}

tests/Unit/SynonymTest.php

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Typesense\Tests\Unit;
6+
7+
use Typesense\Exceptions\Client\ResourceNotFoundException;
8+
9+
test('it can create a multi-way synonym', function () {
10+
$synonym = $this->typesense->synonym->upsert(
11+
$this->collectionName,
12+
$id = $this->slug(),
13+
[
14+
'synonyms' => $synonyms = ['apple', 'banana', 'car'],
15+
],
16+
);
17+
18+
expect($synonym->id)->toBe($id);
19+
20+
expect($synonym->synonyms)->toBe($synonyms);
21+
22+
expect($synonym->root)->toBe('');
23+
});
24+
25+
test('it can create a one-way synonym', function () {
26+
$synonym = $this->typesense->synonym->upsert(
27+
$this->collectionName,
28+
$id = $this->slug(),
29+
[
30+
'root' => $root = 'dog',
31+
'synonyms' => $synonyms = ['apple', 'banana', 'car'],
32+
],
33+
);
34+
35+
expect($synonym->id)->toBe($id);
36+
37+
expect($synonym->synonyms)->toBe($synonyms);
38+
39+
expect($synonym->root)->toBe($root);
40+
});
41+
42+
test('it can retrieve an existing synonym', function () {
43+
$this->typesense->synonym->upsert(
44+
$this->collectionName,
45+
$id = $this->slug(),
46+
[
47+
'synonyms' => [$this->slug()],
48+
],
49+
);
50+
51+
$synonym = $this->typesense->synonym->retrieve(
52+
$this->collectionName,
53+
$id,
54+
);
55+
56+
expect($synonym->id)->toBe($id);
57+
});
58+
59+
test('it can not retrieve a non-existent synonym', function () {
60+
$this->typesense->synonym->retrieve(
61+
$this->collectionName,
62+
$this->slug(),
63+
);
64+
})->throws(ResourceNotFoundException::class);
65+
66+
test('it can list all synonyms', function () {
67+
$synonym = $this->typesense->synonym->upsert(
68+
$this->collectionName,
69+
$this->slug(),
70+
[
71+
'synonyms' => [$this->slug()],
72+
],
73+
);
74+
75+
$synonyms = $this->typesense->synonym->list($this->collectionName);
76+
77+
$ids = array_column($synonyms, 'id');
78+
79+
expect($synonym->id)->toBeIn($ids);
80+
});
81+
82+
test('it can delete an existing synonym', function () {
83+
$synonym = $this->typesense->synonym->upsert(
84+
$this->collectionName,
85+
$this->slug(),
86+
[
87+
'synonyms' => [$this->slug()],
88+
],
89+
);
90+
91+
$deleted = $this->typesense->synonym->delete(
92+
$this->collectionName,
93+
$synonym->id,
94+
);
95+
96+
expect($deleted)->toBeTrue();
97+
});
98+
99+
test('it can not delete a non-existent synonym', function () {
100+
$this->typesense->synonym->delete(
101+
$this->collectionName,
102+
$this->slug(),
103+
);
104+
})->throws(ResourceNotFoundException::class);

0 commit comments

Comments
 (0)