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

v1.10 #44

Merged
merged 4 commits into from
Jul 1, 2024
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
6 changes: 3 additions & 3 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# The version of qdrant to use to download protos
qdrantProtosVersion=v1.9.5
qdrantProtosVersion=v1.10.0

# The version of qdrant docker image to run integration tests against
qdrantVersion=v1.9.5
qdrantVersion=v1.10.0

# The version of the client to generate
packageVersion=1.9.1
packageVersion=1.10.0
101 changes: 101 additions & 0 deletions src/main/java/io/qdrant/client/QdrantClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@
import io.qdrant.client.grpc.Points.PointsOperationResponse;
import io.qdrant.client.grpc.Points.PointsSelector;
import io.qdrant.client.grpc.Points.PointsUpdateOperation;
import io.qdrant.client.grpc.Points.QueryBatchPoints;
import io.qdrant.client.grpc.Points.QueryBatchResponse;
import io.qdrant.client.grpc.Points.QueryPoints;
import io.qdrant.client.grpc.Points.QueryResponse;
import io.qdrant.client.grpc.Points.ReadConsistency;
import io.qdrant.client.grpc.Points.RecommendBatchPoints;
import io.qdrant.client.grpc.Points.RecommendBatchResponse;
Expand Down Expand Up @@ -2746,6 +2750,103 @@ public ListenableFuture<Long> countAsync(
return Futures.transform(future, response -> response.getResult().getCount(), MoreExecutors.directExecutor());
}

/**
* Universally query points.
* Covers all capabilities of search, recommend, discover, filters.
* Also enables hybrid and multi-stage queries.
*
* @param request the query request
* @return a new instance of {@link ListenableFuture}
*/
public ListenableFuture<List<ScoredPoint>> queryAsync(QueryPoints request) {
return queryAsync(request, null);
}

/**
* Universally query points.
* Covers all capabilities of search, recommend, discover, filters.
* Also enables hybrid and multi-stage queries.
*
* @param request the query request
* @param timeout the timeout for the call.
* @return a new instance of {@link ListenableFuture}
*/
public ListenableFuture<List<ScoredPoint>> queryAsync(QueryPoints request, @Nullable Duration timeout) {
Preconditions.checkArgument(
!request.getCollectionName().isEmpty(),
"Collection name must not be empty");

logger.debug("Query on '{}'", request.getCollectionName());
ListenableFuture<QueryResponse> future = getPoints(timeout).query(request);
addLogFailureCallback(future, "Query");
return Futures.transform(future, QueryResponse::getResultList, MoreExecutors.directExecutor());
}

/**
* Universally query points in batch.
* Covers all capabilities of search, recommend, discover, filters.
* Also enables hybrid and multi-stage queries.
*
* @param collectionName The name of the collection
* @param queries The queries to be performed in the batch.
* @return a new instance of {@link ListenableFuture}
*/
public ListenableFuture<List<BatchResult>> queryBatchAsync(
String collectionName,
List<QueryPoints> queries
) {
return queryBatchAsync(collectionName, queries, null, null);
}

/**
* Universally query points in batch.
* Covers all capabilities of search, recommend, discover, filters.
* Also enables hybrid and multi-stage queries.
*
* @param collectionName The name of the collection
* @param queries The queries to be performed in the batch.
* @param readConsistency Options for specifying read consistency guarantees.
* @return a new instance of {@link ListenableFuture}
*/
public ListenableFuture<List<BatchResult>> queryBatchAsync(
String collectionName,
List<QueryPoints> queries,
@Nullable ReadConsistency readConsistency
) {
return queryBatchAsync(collectionName, queries, readConsistency, null);
}

/**
* Universally query points in batch.
* Covers all capabilities of search, recommend, discover, filters.
* Also enables hybrid and multi-stage queries.
*
* @param collectionName The name of the collection
* @param queries The queries to be performed in the batch.
* @param readConsistency Options for specifying read consistency guarantees.
* @param timeout The timeout for the call.
* @return a new instance of {@link ListenableFuture}
*/
public ListenableFuture<List<BatchResult>> queryBatchAsync(
String collectionName,
List<QueryPoints> queries,
@Nullable ReadConsistency readConsistency,
@Nullable Duration timeout
) {
QueryBatchPoints.Builder requestBuilder = QueryBatchPoints.newBuilder()
.setCollectionName(collectionName)
.addAllQueryPoints(queries);

if (readConsistency != null) {
requestBuilder.setReadConsistency(readConsistency);
}

logger.debug("Query batch on '{}'", collectionName);
ListenableFuture<QueryBatchResponse> future = getPoints(timeout).queryBatch(requestBuilder.build());
addLogFailureCallback(future, "Query batch");
return Futures.transform(future, QueryBatchResponse::getResultList, MoreExecutors.directExecutor());
}

//region Snapshot Management

/**
Expand Down
182 changes: 182 additions & 0 deletions src/main/java/io/qdrant/client/QueryFactory.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
package io.qdrant.client;

import java.util.List;
import java.util.UUID;
import io.qdrant.client.grpc.Points.ContextInput;
import io.qdrant.client.grpc.Points.DiscoverInput;
import io.qdrant.client.grpc.Points.Fusion;
import io.qdrant.client.grpc.Points.OrderBy;
import io.qdrant.client.grpc.Points.PointId;
import io.qdrant.client.grpc.Points.Query;
import io.qdrant.client.grpc.Points.RecommendInput;
import io.qdrant.client.grpc.Points.VectorInput;

import static io.qdrant.client.VectorInputFactory.vectorInput;
import static io.qdrant.client.VectorInputFactory.multiVectorInput;


/**
* Convenience methods for constructing {@link Query}
*/
public final class QueryFactory {
private QueryFactory() {
}

/**
* Creates a {@link Query} for recommendation.
*
* @param input An instance of {@link RecommendInput}
* @return a new instance of {@link Query}
*/
public static Query recommend(RecommendInput input) {
return Query.newBuilder().setRecommend(input).build();
}

/**
* Creates a {@link Query} for discovery.
*
* @param input An instance of {@link DiscoverInput}
* @return a new instance of {@link Query}
*/
public static Query discover(DiscoverInput input) {
return Query.newBuilder().setDiscover(input).build();
}

/**
* Creates a {@link Query} for context search.
*
* @param input An instance of {@link ContextInput}
* @return a new instance of {@link Query}
*/
public static Query context(ContextInput input) {
return Query.newBuilder().setContext(input).build();
}

/**
* Creates a {@link Query} for pre-fetch results fusion.
*
* @param fusion An instance of {@link Fusion}
* @return a new instance of {@link Query}
*/
public static Query fusion(Fusion fusion) {
return Query.newBuilder().setFusion(fusion).build();
}

/**
* Creates a {@link Query} to order points by a payload field.
*
* @param key Name of the payload field to order by
* @return a new instance of {@link Query}
*/
public static Query orderBy(String key) {
OrderBy orderBy = OrderBy.newBuilder().setKey(key).build();
return Query.newBuilder().setOrderBy(orderBy).build();
}

/**
* Creates a {@link Query} to order points by a payload field.
*
* @param orderBy An instance of {@link OrderBy}
* @return a new instance of {@link Query}
*/
public static Query orderBy(OrderBy orderBy) {
return Query.newBuilder().setOrderBy(orderBy).build();
}

// region Nearest search queries

/**
* Creates a {@link Query} for nearest search.
*
* @param input An instance of {@link VectorInput}
* @return a new instance of {@link Query}
*/
public static Query nearest(VectorInput input) {
return Query.newBuilder().setNearest(input).build();
}

/**
* Creates a {@link Query} from a list of floats
*
* @param values A map of vector names to values
* @return A new instance of {@link Query}
*/
public static Query nearest(List < Float > values) {
return Query.newBuilder().setNearest(vectorInput(values)).build();
}

/**
* Creates a {@link Query} from a list of floats
*
* @param values A list of values
* @return A new instance of {@link Query}
*/
public static Query nearest(float...values) {
return Query.newBuilder().setNearest(vectorInput(values)).build();
}

/**
* Creates a {@link Query} from a list of floats and integers as indices
*
* @param values The list of floats representing the vector.
* @param indices The list of integers representing the indices.
* @return A new instance of {@link Query}
*/
public static Query nearest(List < Float > values, List < Integer > indices) {
return Query.newBuilder().setNearest(vectorInput(values, indices)).build();
}

/**
* Creates a {@link Query} from a nested array of floats representing a multi
* vector
*
* @param vectors The nested array of floats.
* @return A new instance of {@link Query}
*/
public static Query nearest(float[][] vectors) {
return Query.newBuilder().setNearest(multiVectorInput(vectors)).build();
}

/**
* Creates a {@link Query} from a {@link long}
*
* @param id The point id
* @return a new instance of {@link Query}
*/
public static Query nearest(long id) {
return Query.newBuilder().setNearest(vectorInput(id)).build();
}

/**
* Creates a {@link Query} from a {@link UUID}
*
* @param id The pint id
* @return a new instance of {@link Query}
*/
public static Query nearest(UUID id) {
return Query.newBuilder().setNearest(vectorInput(id)).build();
}

/**
* Creates a {@link Query} from a {@link PointId}
*
* @param id The pint id
* @return a new instance of {@link Query}
*/
public static Query nearest(PointId id) {
return Query.newBuilder().setNearest(vectorInput(id)).build();
}

/**
* Creates a {@link Query} from a nested list of floats representing a multi
* vector
*
* @param vectors The nested list of floats.
* @return A new instance of {@link Query}
*/
public static Query nearestMultiVector(List < List < Float >> vectors) {
return Query.newBuilder().setNearest(multiVectorInput(vectors)).build();
}

// endregion
}
40 changes: 40 additions & 0 deletions src/main/java/io/qdrant/client/VectorFactory.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package io.qdrant.client;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import com.google.common.primitives.Floats;

Expand Down Expand Up @@ -49,4 +51,42 @@ public static Vector vector(List<Float> vector, List<Integer> indices) {
.setIndices(SparseIndices.newBuilder().addAllData(indices).build())
.build();
}

/**
* Creates a multi vector from a nested list of floats
*
* @param vectors The nested list of floats representing the multi vector.
* @return A new instance of {@link Vector}
*/
public static Vector multiVector(List<List<Float>> vectors) {
int vectorSize = vectors.size();
List<Float> flatVector = vectors.stream().flatMap(List::stream).collect(Collectors.toList());

return Vector.newBuilder()
.addAllData(flatVector)
.setVectorsCount(vectorSize)
.build();
}

/**
* Creates a multi vector from a nested array of floats
*
* @param vectors The nested array of floats representing the multi vector.
* @return A new instance of {@link Vector}
*/
public static Vector multiVector(float[][] vectors) {
int vectorSize = vectors.length;

List<Float> flatVector = new ArrayList<>();
for (float[] vector : vectors) {
for (float value : vector) {
flatVector.add(value);
}
}

return Vector.newBuilder()
.addAllData(flatVector)
.setVectorsCount(vectorSize)
.build();
}
}
Loading
Loading