Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PCBC-994 Support for base64 encoded vector types #169

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 25 additions & 11 deletions Couchbase/VectorQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,35 +25,44 @@
class VectorQuery
{
private string $vectorFieldName;
private array $vectorQuery;
private int $numCandidates;
private ?array $vectorQuery = null;
private ?string $base64VectorQuery = null;
private ?float $boost = null;

/**
* @param string $vectorFieldName the document field that contains the vector
* @param array $vectorQuery the vector query to run. Cannot be empty.
* @param array<float>|string $vectorQuery the vector query to run. Cannot be empty. Either a vector array,
* or the vector query encoded into a base64 string.
*
* @since 4.1.7
*
* @throws InvalidArgumentException
*
* @UNCOMMITTED: This API may change in the future.
*/
public function __construct(string $vectorFieldName, array $vectorQuery)
public function __construct(string $vectorFieldName, array|string $vectorQuery)
{
if (empty($vectorQuery)) {
throw new InvalidArgumentException("The vectorQuery cannot be empty");
}

if (is_array($vectorQuery)) {
$this->vectorQuery = $vectorQuery;
} else {
$this->base64VectorQuery = $vectorQuery;
}

$this->vectorFieldName = $vectorFieldName;
$this->vectorQuery = $vectorQuery;
$this->numCandidates = 3;
}

/**
* Static helper to keep code more readable
*
* @param string $vectorFieldName the document field that contains the vector
* @param array $vectorQuery the vector query to run. Cannot be empty.
* @param array<float>|string $vectorQuery the vector query to run. Cannot be empty. Either a vector array,
* or the vector query encoded into a base64 string.
*
* @since 4.1.7
* @return VectorQuery
Expand All @@ -62,15 +71,15 @@ public function __construct(string $vectorFieldName, array $vectorQuery)
*
* @UNCOMMITTED: This API may change in the future.
*/
static function build(string $vectorFieldName, array $vectorQuery): VectorQuery
static function build(string $vectorFieldName, array|string $vectorQuery): VectorQuery
{
return new VectorQuery($vectorFieldName, $vectorQuery);
}

/**
* Sets the number of results that will be returned from this vector query. Defaults to 3.
*
* @param int|null $numCandidates the number of results returned.
* @param int $numCandidates the number of results returned.
*
* @since 4.1.7
* @return VectorQuery
Expand Down Expand Up @@ -122,11 +131,16 @@ public static function export(VectorQuery $query): array
$json['boost'] = $query->boost;
}

$vectorQueries = [];
foreach ($query->vectorQuery as $value) {
$vectorQueries[] = $value;
if ($query->vectorQuery != null) {
$vectorQueries = [];
foreach ($query->vectorQuery as $value) {
$vectorQueries[] = $value;
}
$json['vector'] = $vectorQueries;
} else {
$json['vector_base64'] = $query->base64VectorQuery;
}
$json['vector'] = $vectorQueries;

$json['k'] = $query->numCandidates;
return $json;
}
Expand Down
3 changes: 2 additions & 1 deletion tests/Helpers/CouchbaseTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,8 @@ protected function assertErrorCode($code, $ex)
);
}

protected function fixCavesTimeResolutionOnWindows() {
protected function fixCavesTimeResolutionOnWindows()
{
if (PHP_OS_FAMILY === 'Windows' && self::env()->useCaves()) {
usleep(1);
}
Expand Down
17 changes: 17 additions & 0 deletions tests/SearchTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@
}


public function testSearchWithConsistency()

Check failure on line 207 in tests/SearchTest.php

View workflow job for this annotation

GitHub Actions / server_linux_x86_64 (8.3, nts, 7.0.5)

/home/runner/work/couchbase-php-client/couchbase-php-client/tests/SearchTest.php.testSearchWithConsistency

SearchTest::testSearchWithConsistency Exception: Excepted rows to not to be empty

Check failure on line 207 in tests/SearchTest.php

View workflow job for this annotation

GitHub Actions / server_linux_x86_64 (8.3, zts, 7.6.0)

/home/runner/work/couchbase-php-client/couchbase-php-client/tests/SearchTest.php.testSearchWithConsistency

SearchTest::testSearchWithConsistency Couchbase\Exception\AmbiguousTimeoutException: ambiguous_timeout (13): "unable to execute HTTP operation "search_query""

Check failure on line 207 in tests/SearchTest.php

View workflow job for this annotation

GitHub Actions / server_linux_x86_64 (8.3, zts, 7.0.5)

/home/runner/work/couchbase-php-client/couchbase-php-client/tests/SearchTest.php.testSearchWithConsistency

SearchTest::testSearchWithConsistency Exception: Excepted rows to not to be empty
{
$this->skipIfCaves();

Expand Down Expand Up @@ -392,7 +392,7 @@
}
}

public function testCompoundSearchQueries()

Check failure on line 395 in tests/SearchTest.php

View workflow job for this annotation

GitHub Actions / server_linux_x86_64 (8.3, zts, 7.6.0)

/home/runner/work/couchbase-php-client/couchbase-php-client/tests/SearchTest.php.testCompoundSearchQueries

SearchTest::testCompoundSearchQueries Failed asserting that 6 is equal to 10 or is greater than 10.
{
$this->skipIfCaves();

Expand Down Expand Up @@ -431,7 +431,7 @@
);
}

public function testSearchWithFragments()

Check failure on line 434 in tests/SearchTest.php

View workflow job for this annotation

GitHub Actions / server_linux_x86_64 (8.3, zts, 7.6.0)

/home/runner/work/couchbase-php-client/couchbase-php-client/tests/SearchTest.php.testSearchWithFragments

SearchTest::testSearchWithFragments Failed asserting that 'Samuel Adams Hallertau Imperial Pilsner' matches PCRE pattern "/<mark>/".
{
$this->skipIfCaves();

Expand All @@ -453,7 +453,7 @@
}
}

public function testSearchWithFacets()

Check failure on line 456 in tests/SearchTest.php

View workflow job for this annotation

GitHub Actions / server_linux_x86_64 (8.3, nts, 7.0.5)

/home/runner/work/couchbase-php-client/couchbase-php-client/tests/SearchTest.php.testSearchWithFacets

SearchTest::testSearchWithFacets Failed asserting that 9 is equal to 10 or is greater than 10.

Check failure on line 456 in tests/SearchTest.php

View workflow job for this annotation

GitHub Actions / server_linux_x86_64 (8.3, zts, 7.6.0)

/home/runner/work/couchbase-php-client/couchbase-php-client/tests/SearchTest.php.testSearchWithFacets

SearchTest::testSearchWithFacets Failed asserting that 8 is equal to 10 or is greater than 10.
{
$this->skipIfCaves();

Expand Down Expand Up @@ -597,6 +597,23 @@
$this->assertEquals('{"match_none":"null"}', $encodedSearchQuery);
}

public function testVectorSearchEmptyStringThrowsInvalidArgument()
{
$this->expectException(\Couchbase\Exception\InvalidArgumentException::class);
VectorQuery::build("vectorField", "");
}

public function testVectorSearchEncodingWithBase64()
{
$base64EncodedVector = "aOeYBEXJ4kI=";
$vectorQueryOne = VectorQuery::build("foo", $base64EncodedVector)->boost(0.5)->numCandidates(4);
$vectorQueryTwo = VectorQuery::build("bar", [-0.00810353, 0.6433, 0.52364]);
$searchRequest = SearchRequest::export(SearchRequest::build(VectorSearch::build([$vectorQueryOne, $vectorQueryTwo])));
$encodedVectorQuery = json_encode($searchRequest['vectorSearch']);
$this->assertEquals(JSON_ERROR_NONE, json_last_error());
$this->assertEquals(sprintf('[{"field":"foo","boost":0.5,"vector_base64":"%s","k":4},{"field":"bar","vector":[-0.00810353,0.6433,0.52364],"k":3}]', $base64EncodedVector), $encodedVectorQuery);
}

public function testScopeSearch()
{
$this->skipIfCaves();
Expand Down
Loading