Skip to content

Commit f059e45

Browse files
committed
FIT: Base64 vector search in Java & Kotlin
Change-Id: I6e9492ee79ae675604cb82f9b0e04205ee6f85e1 Reviewed-on: https://review.couchbase.org/c/couchbase-jvm-clients/+/210824 Reviewed-by: David Nault <[email protected]> Tested-by: Build Bot <[email protected]>
1 parent 8ada25a commit f059e45

File tree

4 files changed

+63
-26
lines changed

4 files changed

+63
-26
lines changed

java-fit-performer/src/main/java/com/couchbase/search/SearchHelper.java

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,6 @@
7979
import com.couchbase.client.protocol.sdk.search.indexmanager.UpsertIndex;
8080
import com.couchbase.client.protocol.sdk.search.BlockingSearchResult;
8181
import com.couchbase.client.protocol.sdk.search.Location;
82-
import com.couchbase.client.protocol.sdk.search.Search;
8382
import com.couchbase.client.protocol.sdk.search.SearchFacetResult;
8483
import com.couchbase.client.protocol.sdk.search.SearchFacets;
8584
import com.couchbase.client.protocol.sdk.search.SearchFragments;
@@ -89,6 +88,7 @@
8988
import com.couchbase.client.protocol.shared.ContentAs;
9089
import com.couchbase.stream.ReactiveSearchResultStreamer;
9190
import com.couchbase.utils.ContentAsUtil;
91+
import com.google.common.primitives.Floats;
9292
import com.google.protobuf.ByteString;
9393
import com.google.protobuf.Timestamp;
9494
import reactor.core.publisher.Mono;
@@ -1439,6 +1439,41 @@ static AnalyzeDocumentOptions createOptions(AnalyzeDocument request, ConcurrentH
14391439
return out;
14401440
}
14411441

1442+
// pre-processor doesn't support nested tags, so do this intricate dance
1443+
// [start:3.6.0]
1444+
private static VectorQuery toSdk(com.couchbase.client.protocol.sdk.search.VectorQuery fit) {
1445+
// [end:3.6.0]
1446+
1447+
// [start:3.6.3]
1448+
if (fit.hasBase64VectorQuery()) {
1449+
VectorQuery sdk = VectorQuery.create(fit.getVectorFieldName(), fit.getBase64VectorQuery());
1450+
applyVectorQueryOptions(sdk, fit);
1451+
return sdk;
1452+
}
1453+
// [end:3.6.3]
1454+
1455+
// [start:3.6.0]
1456+
var floats = Floats.toArray(fit.getVectorQueryList());
1457+
VectorQuery sdk = VectorQuery.create(fit.getVectorFieldName(), floats);
1458+
applyVectorQueryOptions(sdk, fit);
1459+
return sdk;
1460+
}
1461+
// [end:3.6.0]
1462+
1463+
// [start:3.6.0]
1464+
private static void applyVectorQueryOptions(VectorQuery sdk, com.couchbase.client.protocol.sdk.search.VectorQuery fit) {
1465+
if (fit.hasOptions()) {
1466+
var opts = fit.getOptions();
1467+
if (opts.hasNumCandidates()) {
1468+
sdk.numCandidates(opts.getNumCandidates());
1469+
}
1470+
if (opts.hasBoost()) {
1471+
sdk.boost(opts.getBoost());
1472+
}
1473+
}
1474+
}
1475+
// [end:3.6.0]
1476+
14421477
// [start:3.6.0]
14431478
private static SearchRequest convertSearchRequest(com.couchbase.client.protocol.sdk.search.SearchRequest sr) {
14441479
if (sr.hasSearchQuery()) {
@@ -1456,23 +1491,7 @@ else if (sr.hasVectorSearch()) {
14561491

14571492
private static VectorSearch convertVectorSearch(com.couchbase.client.protocol.sdk.search.VectorSearch vs) {
14581493
var vectors = vs.getVectorQueryList().stream()
1459-
.map(v -> {
1460-
var buffer = new float[v.getVectorQueryCount()];
1461-
for (int i = 0; i < v.getVectorQueryList().size(); i++) {
1462-
buffer[i] = v.getVectorQuery(i);
1463-
}
1464-
var out = VectorQuery.create(v.getVectorFieldName(), buffer);
1465-
if (v.hasOptions()) {
1466-
var opts = v.getOptions();
1467-
if (opts.hasNumCandidates()) {
1468-
out = out.numCandidates(opts.getNumCandidates());
1469-
}
1470-
if (opts.hasBoost()) {
1471-
out = out.boost(opts.getBoost());
1472-
}
1473-
}
1474-
return out;
1475-
})
1494+
.map(SearchHelper::toSdk)
14761495
.toList();
14771496
if (vs.hasOptions()) {
14781497
return VectorSearch.create(vectors, convertVectorSearchOptions(vs.getOptions()));

java-fit-performer/src/main/java/com/couchbase/utils/Capabilities.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,10 @@ public static List<Caps> sdkImplementationCaps() {
8080
out.add(Caps.SDK_VECTOR_SEARCH);
8181
// [end:3.6.0]
8282

83+
// [start:3.6.3]
84+
out.add(Caps.SDK_VECTOR_SEARCH_BASE64);
85+
// [end:3.6.3]
86+
8387
return out;
8488
}
8589
}

kotlin-fit-performer/src/main/kotlin/com/couchbase/client/performer/kotlin/KotlinPerformer.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ class KotlinPerformer : CorePerformer() {
5555
.addSdkImplementationCaps(Caps.SDK_SEARCH)
5656
.addSdkImplementationCaps(Caps.SDK_SCOPE_SEARCH)
5757
.addSdkImplementationCaps(Caps.SDK_VECTOR_SEARCH)
58+
.addSdkImplementationCaps(Caps.SDK_VECTOR_SEARCH_BASE64)
5859
.addSdkImplementationCaps(Caps.SDK_SEARCH_INDEX_MANAGEMENT)
5960
.addSdkImplementationCaps(Caps.SDK_SCOPE_SEARCH_INDEX_MANAGEMENT)
6061
.addPerformerCaps(PerformerCaps.CLUSTER_CONFIG_CERT)

kotlin-fit-performer/src/main/kotlin/com/couchbase/client/performer/kotlin/search/SearchHelper.kt

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -452,14 +452,27 @@ private fun FitVectorSearch.toSdk(): VectorSearchSpec {
452452
}
453453

454454
private fun FitVectorQuery.toSdk(): VectorQuery {
455-
val query = if (!hasOptions() || !options.hasNumCandidates())
456-
SearchSpec.vector(vectorFieldName, vectorQueryList.toFloatArray())
457-
else
458-
SearchSpec.vector(
459-
field = vectorFieldName,
460-
vector = vectorQueryList.toFloatArray(),
461-
numCandidates = options.numCandidates,
462-
)
455+
val query: VectorQuery
456+
457+
if (hasBase64VectorQuery()) {
458+
query = if (!hasOptions() || !options.hasNumCandidates())
459+
SearchSpec.vector(vectorFieldName, base64VectorQuery)
460+
else
461+
SearchSpec.vector(
462+
field = vectorFieldName,
463+
vector = base64VectorQuery,
464+
numCandidates = options.numCandidates,
465+
)
466+
} else {
467+
query = if (!hasOptions() || !options.hasNumCandidates())
468+
SearchSpec.vector(vectorFieldName, vectorQueryList.toFloatArray())
469+
else
470+
SearchSpec.vector(
471+
field = vectorFieldName,
472+
vector = vectorQueryList.toFloatArray(),
473+
numCandidates = options.numCandidates,
474+
)
475+
}
463476

464477
return query.maybeBoost(hasOptions() && options.hasBoost(), options.boost)
465478
}

0 commit comments

Comments
 (0)