Skip to content

Commit 5b69412

Browse files
authored
Merge pull request hkulekci#14 from gregpriday/feature/multiple-vector-support
Multiple Vector Support
2 parents 8e62cb1 + cda9f1f commit 5b69412

16 files changed

Lines changed: 415 additions & 28 deletions

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,5 @@ vendor/
22
.phpunit.result.cache
33
.phpunit.cache
44
coverage
5-
/qdrant_storage
65
/composer.lock
76
/.idea

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"require": {
77
"php": "^8.1",
88
"psr/http-client": "^1.0",
9-
"psr/http-message": "^1.0",
9+
"psr/http-message": "^1.0|^2.0",
1010
"psr/log": "^1.0|^2.0|^3.0",
1111
"guzzlehttp/guzzle": "^7.5",
1212
"guzzlehttp/psr7": "^2.0",

src/Exception/InvalidArgumentException.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
use Qdrant\Response;
1212

13-
class InvalidArgumentException extends \Exception
13+
class InvalidArgumentException extends \InvalidArgumentException
1414
{
1515
protected Response $response;
1616

src/Models/MultiVectorStruct.php

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?php
2+
3+
namespace Qdrant\Models;
4+
5+
use Qdrant\Exception\InvalidArgumentException;
6+
7+
class MultiVectorStruct implements VectorStructInterface
8+
{
9+
protected array $vectors = [];
10+
11+
public function __construct(array $vectors = [])
12+
{
13+
foreach ($vectors as $name => $vector) {
14+
$this->addVector($name, $vector);
15+
}
16+
}
17+
18+
public function addVector(string $name, array $vector): void
19+
{
20+
$this->vectors[$name] = $vector;
21+
}
22+
23+
public function getName(): string
24+
{
25+
if(empty($this->vectors)) {
26+
throw new InvalidArgumentException("No vectors added yet");
27+
}
28+
29+
return array_key_first($this->vectors);
30+
}
31+
32+
public function toSearchArray(string $name = null): array
33+
{
34+
// Throw an error if no name is given
35+
if ($name === null) {
36+
throw new InvalidArgumentException("Must provide a name to search");
37+
}
38+
39+
if(!isset($this->vectors[$name])) {
40+
throw new InvalidArgumentException("Vector with name $name not found");
41+
}
42+
43+
return [
44+
'name' => $name,
45+
'vector' => $this->vectors[$name],
46+
];
47+
}
48+
49+
public function toArray(): array
50+
{
51+
return $this->vectors;
52+
}
53+
54+
public function count(): int
55+
{
56+
return count($this->vectors);
57+
}
58+
}

src/Models/PointStruct.php

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,11 @@ class PointStruct
1515
{
1616
use ProtectedPropertyAccessor;
1717

18-
// TODO: we need a solution for point with uuid
1918
protected int|string $id;
2019
protected ?array $payload = null;
21-
protected VectorStruct $vector;
20+
protected VectorStructInterface $vector;
2221

23-
public function __construct(int|string $id, VectorStruct $vector, array $payload = null)
22+
public function __construct(int|string $id, VectorStructInterface $vector, array $payload = null)
2423
{
2524
$this->id = $id;
2625
$this->vector = $vector;
@@ -33,9 +32,17 @@ public static function createFromArray(array $pointArray): PointStruct
3332
if (count(array_intersect_key(array_flip($required), $pointArray)) !== count($required)) {
3433
throw new InvalidArgumentException('Missing point keys');
3534
}
35+
3636
$vector = $pointArray['vector'];
37-
if (is_array($pointArray['vector'])) {
38-
$vector = new VectorStruct($pointArray['vector'], $pointArray['name'] ?? null);
37+
38+
// Check if it's an array and convert it to a VectorStruct
39+
if (is_array($vector)) {
40+
$vector = new VectorStruct($vector, $pointArray['name'] ?? null);
41+
}
42+
43+
// Check if it's already a VectorStruct or MultiVectorStruct
44+
if (!($vector instanceof VectorStructInterface)) {
45+
throw new InvalidArgumentException('Invalid vector type');
3946
}
4047

4148
return new PointStruct($pointArray['id'], $vector, $pointArray['payload'] ?? null);
@@ -55,26 +62,17 @@ public function toArray(): array
5562
return $point;
5663
}
5764

58-
/**
59-
* @return int
60-
*/
6165
public function getId(): int|string
6266
{
6367
return $this->id;
6468
}
6569

66-
/**
67-
* @return array|null
68-
*/
6970
public function getPayload(): ?array
7071
{
7172
return $this->payload;
7273
}
7374

74-
/**
75-
* @return VectorStruct
76-
*/
77-
public function getVector(): VectorStruct
75+
public function getVector(): VectorStructInterface
7876
{
7977
return $this->vector;
8078
}

src/Models/PointsStruct.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,9 @@ public function toArray(): array
4646

4747
return $points;
4848
}
49+
50+
public function count(): int
51+
{
52+
return count($this->points);
53+
}
4954
}

src/Models/Request/Point.php

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,26 @@
88

99
namespace Qdrant\Models\Request;
1010

11+
use Qdrant\Models\MultiVectorStruct;
12+
use Qdrant\Models\VectorStruct;
13+
use Qdrant\Models\VectorStructInterface;
14+
1115
class Point implements RequestModel
1216
{
1317
protected string $id;
14-
protected array $vector;
18+
protected VectorStructInterface $vector;
1519

1620
/**
1721
* @var array|null Payload values (optional)
1822
*/
1923
protected ?array $payload = null;
2024

21-
public function __construct(string $id, array $vector, array $payload = null)
25+
public function __construct(string $id, VectorStructInterface|array $vector, array $payload = null)
2226
{
27+
if(is_array($vector)) {
28+
$vector = new VectorStruct($vector);
29+
}
30+
2331
$this->id = $id;
2432
$this->vector = $vector;
2533
$this->payload = $payload;
@@ -29,7 +37,7 @@ public function toArray(): array
2937
{
3038
$data = [
3139
'id' => $this->id,
32-
'vector' => $this->vector,
40+
'vector' => $this->vector->toArray(),
3341
];
3442

3543
if ($this->payload) {

src/Models/Request/SearchRequest.php

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
use Qdrant\Models\Filter\Filter;
1111
use Qdrant\Models\Traits\ProtectedPropertyAccessor;
12-
use Qdrant\Models\VectorStruct;
12+
use Qdrant\Models\VectorStructInterface;
1313

1414
class SearchRequest
1515
{
@@ -19,7 +19,7 @@ class SearchRequest
1919

2020
protected array $params = [];
2121

22-
protected VectorStruct $vector;
22+
protected VectorStructInterface $vector;
2323

2424
protected ?int $limit = null;
2525

@@ -31,11 +31,20 @@ class SearchRequest
3131

3232
protected ?float $scoreThreshold = null;
3333

34-
public function __construct(VectorStruct $vector)
34+
protected ?string $name = null;
35+
36+
public function __construct(VectorStructInterface $vector)
3537
{
3638
$this->vector = $vector;
3739
}
3840

41+
public function setName(string $name): static
42+
{
43+
$this->name = $name;
44+
45+
return $this;
46+
}
47+
3948
public function setFilter(Filter $filter): static
4049
{
4150
$this->filter = $filter;
@@ -88,8 +97,9 @@ public function setWithVector($withVector): static
8897
public function toArray(): array
8998
{
9099
$body = [
91-
'vector' => $this->vector->toSearch(),
100+
'vector' => $this->vector->toSearchArray($this->name ?? $this->vector->getName()),
92101
];
102+
93103
if ($this->filter !== null && $this->filter->toArray()) {
94104
$body['filter'] = $this->filter->toArray();
95105
}

src/Models/VectorStruct.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
use Qdrant\Models\Traits\ProtectedPropertyAccessor;
1010

11-
class VectorStruct
11+
class VectorStruct implements VectorStructInterface
1212
{
1313
use ProtectedPropertyAccessor;
1414

@@ -26,7 +26,12 @@ public function isNamed(): bool
2626
return $this->name !== null;
2727
}
2828

29-
public function toSearch(): array
29+
public function getName(): string
30+
{
31+
return $this->name;
32+
}
33+
34+
public function toSearchArray(string $name = null): array
3035
{
3136
if ($this->isNamed()) {
3237
return [
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
namespace Qdrant\Models;
4+
5+
interface VectorStructInterface
6+
{
7+
/**
8+
* Get the name of the vector
9+
*
10+
* @return string
11+
*/
12+
public function getName(): string;
13+
14+
/**
15+
* Convert this vector to a search array.
16+
*
17+
* @param string|null $name
18+
* @return array
19+
*/
20+
public function toSearchArray(string $name = null): array;
21+
22+
/**
23+
* Convert this vector an array for Point and PointsBatch.
24+
*
25+
* @return array
26+
*/
27+
public function toArray(): array;
28+
}

0 commit comments

Comments
 (0)