Skip to content

Commit 25e3b5a

Browse files
authored
Merge pull request #44 from qdrant/1-10
v1.10
2 parents 084af1e + 98eafec commit 25e3b5a

File tree

7 files changed

+606
-3
lines changed

7 files changed

+606
-3
lines changed

gradle.properties

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# The version of qdrant to use to download protos
2-
qdrantProtosVersion=v1.9.5
2+
qdrantProtosVersion=v1.10.0
33

44
# The version of qdrant docker image to run integration tests against
5-
qdrantVersion=v1.9.5
5+
qdrantVersion=v1.10.0
66

77
# The version of the client to generate
8-
packageVersion=1.9.1
8+
packageVersion=1.10.0

src/main/java/io/qdrant/client/QdrantClient.java

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@
7777
import io.qdrant.client.grpc.Points.PointsOperationResponse;
7878
import io.qdrant.client.grpc.Points.PointsSelector;
7979
import io.qdrant.client.grpc.Points.PointsUpdateOperation;
80+
import io.qdrant.client.grpc.Points.QueryBatchPoints;
81+
import io.qdrant.client.grpc.Points.QueryBatchResponse;
82+
import io.qdrant.client.grpc.Points.QueryPoints;
83+
import io.qdrant.client.grpc.Points.QueryResponse;
8084
import io.qdrant.client.grpc.Points.ReadConsistency;
8185
import io.qdrant.client.grpc.Points.RecommendBatchPoints;
8286
import io.qdrant.client.grpc.Points.RecommendBatchResponse;
@@ -2746,6 +2750,103 @@ public ListenableFuture<Long> countAsync(
27462750
return Futures.transform(future, response -> response.getResult().getCount(), MoreExecutors.directExecutor());
27472751
}
27482752

2753+
/**
2754+
* Universally query points.
2755+
* Covers all capabilities of search, recommend, discover, filters.
2756+
* Also enables hybrid and multi-stage queries.
2757+
*
2758+
* @param request the query request
2759+
* @return a new instance of {@link ListenableFuture}
2760+
*/
2761+
public ListenableFuture<List<ScoredPoint>> queryAsync(QueryPoints request) {
2762+
return queryAsync(request, null);
2763+
}
2764+
2765+
/**
2766+
* Universally query points.
2767+
* Covers all capabilities of search, recommend, discover, filters.
2768+
* Also enables hybrid and multi-stage queries.
2769+
*
2770+
* @param request the query request
2771+
* @param timeout the timeout for the call.
2772+
* @return a new instance of {@link ListenableFuture}
2773+
*/
2774+
public ListenableFuture<List<ScoredPoint>> queryAsync(QueryPoints request, @Nullable Duration timeout) {
2775+
Preconditions.checkArgument(
2776+
!request.getCollectionName().isEmpty(),
2777+
"Collection name must not be empty");
2778+
2779+
logger.debug("Query on '{}'", request.getCollectionName());
2780+
ListenableFuture<QueryResponse> future = getPoints(timeout).query(request);
2781+
addLogFailureCallback(future, "Query");
2782+
return Futures.transform(future, QueryResponse::getResultList, MoreExecutors.directExecutor());
2783+
}
2784+
2785+
/**
2786+
* Universally query points in batch.
2787+
* Covers all capabilities of search, recommend, discover, filters.
2788+
* Also enables hybrid and multi-stage queries.
2789+
*
2790+
* @param collectionName The name of the collection
2791+
* @param queries The queries to be performed in the batch.
2792+
* @return a new instance of {@link ListenableFuture}
2793+
*/
2794+
public ListenableFuture<List<BatchResult>> queryBatchAsync(
2795+
String collectionName,
2796+
List<QueryPoints> queries
2797+
) {
2798+
return queryBatchAsync(collectionName, queries, null, null);
2799+
}
2800+
2801+
/**
2802+
* Universally query points in batch.
2803+
* Covers all capabilities of search, recommend, discover, filters.
2804+
* Also enables hybrid and multi-stage queries.
2805+
*
2806+
* @param collectionName The name of the collection
2807+
* @param queries The queries to be performed in the batch.
2808+
* @param readConsistency Options for specifying read consistency guarantees.
2809+
* @return a new instance of {@link ListenableFuture}
2810+
*/
2811+
public ListenableFuture<List<BatchResult>> queryBatchAsync(
2812+
String collectionName,
2813+
List<QueryPoints> queries,
2814+
@Nullable ReadConsistency readConsistency
2815+
) {
2816+
return queryBatchAsync(collectionName, queries, readConsistency, null);
2817+
}
2818+
2819+
/**
2820+
* Universally query points in batch.
2821+
* Covers all capabilities of search, recommend, discover, filters.
2822+
* Also enables hybrid and multi-stage queries.
2823+
*
2824+
* @param collectionName The name of the collection
2825+
* @param queries The queries to be performed in the batch.
2826+
* @param readConsistency Options for specifying read consistency guarantees.
2827+
* @param timeout The timeout for the call.
2828+
* @return a new instance of {@link ListenableFuture}
2829+
*/
2830+
public ListenableFuture<List<BatchResult>> queryBatchAsync(
2831+
String collectionName,
2832+
List<QueryPoints> queries,
2833+
@Nullable ReadConsistency readConsistency,
2834+
@Nullable Duration timeout
2835+
) {
2836+
QueryBatchPoints.Builder requestBuilder = QueryBatchPoints.newBuilder()
2837+
.setCollectionName(collectionName)
2838+
.addAllQueryPoints(queries);
2839+
2840+
if (readConsistency != null) {
2841+
requestBuilder.setReadConsistency(readConsistency);
2842+
}
2843+
2844+
logger.debug("Query batch on '{}'", collectionName);
2845+
ListenableFuture<QueryBatchResponse> future = getPoints(timeout).queryBatch(requestBuilder.build());
2846+
addLogFailureCallback(future, "Query batch");
2847+
return Futures.transform(future, QueryBatchResponse::getResultList, MoreExecutors.directExecutor());
2848+
}
2849+
27492850
//region Snapshot Management
27502851

27512852
/**
Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
package io.qdrant.client;
2+
3+
import java.util.List;
4+
import java.util.UUID;
5+
import io.qdrant.client.grpc.Points.ContextInput;
6+
import io.qdrant.client.grpc.Points.DiscoverInput;
7+
import io.qdrant.client.grpc.Points.Fusion;
8+
import io.qdrant.client.grpc.Points.OrderBy;
9+
import io.qdrant.client.grpc.Points.PointId;
10+
import io.qdrant.client.grpc.Points.Query;
11+
import io.qdrant.client.grpc.Points.RecommendInput;
12+
import io.qdrant.client.grpc.Points.VectorInput;
13+
14+
import static io.qdrant.client.VectorInputFactory.vectorInput;
15+
import static io.qdrant.client.VectorInputFactory.multiVectorInput;
16+
17+
18+
/**
19+
* Convenience methods for constructing {@link Query}
20+
*/
21+
public final class QueryFactory {
22+
private QueryFactory() {
23+
}
24+
25+
/**
26+
* Creates a {@link Query} for recommendation.
27+
*
28+
* @param input An instance of {@link RecommendInput}
29+
* @return a new instance of {@link Query}
30+
*/
31+
public static Query recommend(RecommendInput input) {
32+
return Query.newBuilder().setRecommend(input).build();
33+
}
34+
35+
/**
36+
* Creates a {@link Query} for discovery.
37+
*
38+
* @param input An instance of {@link DiscoverInput}
39+
* @return a new instance of {@link Query}
40+
*/
41+
public static Query discover(DiscoverInput input) {
42+
return Query.newBuilder().setDiscover(input).build();
43+
}
44+
45+
/**
46+
* Creates a {@link Query} for context search.
47+
*
48+
* @param input An instance of {@link ContextInput}
49+
* @return a new instance of {@link Query}
50+
*/
51+
public static Query context(ContextInput input) {
52+
return Query.newBuilder().setContext(input).build();
53+
}
54+
55+
/**
56+
* Creates a {@link Query} for pre-fetch results fusion.
57+
*
58+
* @param fusion An instance of {@link Fusion}
59+
* @return a new instance of {@link Query}
60+
*/
61+
public static Query fusion(Fusion fusion) {
62+
return Query.newBuilder().setFusion(fusion).build();
63+
}
64+
65+
/**
66+
* Creates a {@link Query} to order points by a payload field.
67+
*
68+
* @param key Name of the payload field to order by
69+
* @return a new instance of {@link Query}
70+
*/
71+
public static Query orderBy(String key) {
72+
OrderBy orderBy = OrderBy.newBuilder().setKey(key).build();
73+
return Query.newBuilder().setOrderBy(orderBy).build();
74+
}
75+
76+
/**
77+
* Creates a {@link Query} to order points by a payload field.
78+
*
79+
* @param orderBy An instance of {@link OrderBy}
80+
* @return a new instance of {@link Query}
81+
*/
82+
public static Query orderBy(OrderBy orderBy) {
83+
return Query.newBuilder().setOrderBy(orderBy).build();
84+
}
85+
86+
// region Nearest search queries
87+
88+
/**
89+
* Creates a {@link Query} for nearest search.
90+
*
91+
* @param input An instance of {@link VectorInput}
92+
* @return a new instance of {@link Query}
93+
*/
94+
public static Query nearest(VectorInput input) {
95+
return Query.newBuilder().setNearest(input).build();
96+
}
97+
98+
/**
99+
* Creates a {@link Query} from a list of floats
100+
*
101+
* @param values A map of vector names to values
102+
* @return A new instance of {@link Query}
103+
*/
104+
public static Query nearest(List < Float > values) {
105+
return Query.newBuilder().setNearest(vectorInput(values)).build();
106+
}
107+
108+
/**
109+
* Creates a {@link Query} from a list of floats
110+
*
111+
* @param values A list of values
112+
* @return A new instance of {@link Query}
113+
*/
114+
public static Query nearest(float...values) {
115+
return Query.newBuilder().setNearest(vectorInput(values)).build();
116+
}
117+
118+
/**
119+
* Creates a {@link Query} from a list of floats and integers as indices
120+
*
121+
* @param values The list of floats representing the vector.
122+
* @param indices The list of integers representing the indices.
123+
* @return A new instance of {@link Query}
124+
*/
125+
public static Query nearest(List < Float > values, List < Integer > indices) {
126+
return Query.newBuilder().setNearest(vectorInput(values, indices)).build();
127+
}
128+
129+
/**
130+
* Creates a {@link Query} from a nested array of floats representing a multi
131+
* vector
132+
*
133+
* @param vectors The nested array of floats.
134+
* @return A new instance of {@link Query}
135+
*/
136+
public static Query nearest(float[][] vectors) {
137+
return Query.newBuilder().setNearest(multiVectorInput(vectors)).build();
138+
}
139+
140+
/**
141+
* Creates a {@link Query} from a {@link long}
142+
*
143+
* @param id The point id
144+
* @return a new instance of {@link Query}
145+
*/
146+
public static Query nearest(long id) {
147+
return Query.newBuilder().setNearest(vectorInput(id)).build();
148+
}
149+
150+
/**
151+
* Creates a {@link Query} from a {@link UUID}
152+
*
153+
* @param id The pint id
154+
* @return a new instance of {@link Query}
155+
*/
156+
public static Query nearest(UUID id) {
157+
return Query.newBuilder().setNearest(vectorInput(id)).build();
158+
}
159+
160+
/**
161+
* Creates a {@link Query} from a {@link PointId}
162+
*
163+
* @param id The pint id
164+
* @return a new instance of {@link Query}
165+
*/
166+
public static Query nearest(PointId id) {
167+
return Query.newBuilder().setNearest(vectorInput(id)).build();
168+
}
169+
170+
/**
171+
* Creates a {@link Query} from a nested list of floats representing a multi
172+
* vector
173+
*
174+
* @param vectors The nested list of floats.
175+
* @return A new instance of {@link Query}
176+
*/
177+
public static Query nearestMultiVector(List < List < Float >> vectors) {
178+
return Query.newBuilder().setNearest(multiVectorInput(vectors)).build();
179+
}
180+
181+
// endregion
182+
}

src/main/java/io/qdrant/client/VectorFactory.java

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package io.qdrant.client;
22

3+
import java.util.ArrayList;
34
import java.util.List;
5+
import java.util.stream.Collectors;
46

57
import com.google.common.primitives.Floats;
68

@@ -49,4 +51,42 @@ public static Vector vector(List<Float> vector, List<Integer> indices) {
4951
.setIndices(SparseIndices.newBuilder().addAllData(indices).build())
5052
.build();
5153
}
54+
55+
/**
56+
* Creates a multi vector from a nested list of floats
57+
*
58+
* @param vectors The nested list of floats representing the multi vector.
59+
* @return A new instance of {@link Vector}
60+
*/
61+
public static Vector multiVector(List<List<Float>> vectors) {
62+
int vectorSize = vectors.size();
63+
List<Float> flatVector = vectors.stream().flatMap(List::stream).collect(Collectors.toList());
64+
65+
return Vector.newBuilder()
66+
.addAllData(flatVector)
67+
.setVectorsCount(vectorSize)
68+
.build();
69+
}
70+
71+
/**
72+
* Creates a multi vector from a nested array of floats
73+
*
74+
* @param vectors The nested array of floats representing the multi vector.
75+
* @return A new instance of {@link Vector}
76+
*/
77+
public static Vector multiVector(float[][] vectors) {
78+
int vectorSize = vectors.length;
79+
80+
List<Float> flatVector = new ArrayList<>();
81+
for (float[] vector : vectors) {
82+
for (float value : vector) {
83+
flatVector.add(value);
84+
}
85+
}
86+
87+
return Vector.newBuilder()
88+
.addAllData(flatVector)
89+
.setVectorsCount(vectorSize)
90+
.build();
91+
}
5292
}

0 commit comments

Comments
 (0)