Skip to content

Commit 23cfac0

Browse files
authored
v1.8.0 (#26)
* v1.8.0 * chore: StartFromFactory * chore: bump to v1.8.0 * chore: resolve imports
1 parent 1678c56 commit 23cfac0

File tree

6 files changed

+200
-4
lines changed

6 files changed

+200
-4
lines changed

build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ tasks.register('downloadProtos') {
116116
def outputDirectory = outputs.files.singleFile.toPath().toString()
117117
def protoFileRegex = Pattern.compile(".*?lib/api/src/grpc/proto/.*?.proto")
118118
try (def httpClient = HttpClients.createDefault()) {
119-
def url = "https://api.github.com/repos/qdrant/qdrant/tarball/refs/tags/${qdrantProtosVersion}"
119+
def url = "https://api.github.com/repos/qdrant/qdrant/tarball/${qdrantProtosVersion}"
120120
logger.debug("downloading protos from {}", url)
121121
def response = httpClient.execute(new HttpGet(url))
122122
try (InputStream tarballStream = response.getEntity().getContent()) {

gradle.properties

+3-3
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.7.0
2+
qdrantProtosVersion=v1.8.0
33

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

77
# The version of the client to generate
8-
packageVersion=1.7.2
8+
packageVersion=1.8.0

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

+18
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import java.util.List;
44

55
import io.qdrant.client.grpc.Points.Condition;
6+
import io.qdrant.client.grpc.Points.DatetimeRange;
67
import io.qdrant.client.grpc.Points.FieldCondition;
78
import io.qdrant.client.grpc.Points.Filter;
89
import io.qdrant.client.grpc.Points.GeoBoundingBox;
@@ -370,4 +371,21 @@ public static Condition filter(Filter filter) {
370371
.setFilter(filter)
371372
.build();
372373
}
374+
375+
/**
376+
* Matches records where the given field has a datetime value within the
377+
* specified range
378+
*
379+
* @param field The name of the field.
380+
* @param datetimeRange The datetime range to match.
381+
* @return a new instance of {@link Condition}
382+
*/
383+
public static Condition datetimeRange(String field, DatetimeRange datetimeRange) {
384+
return Condition.newBuilder()
385+
.setField(FieldCondition.newBuilder()
386+
.setKey(field)
387+
.setDatetimeRange(datetimeRange)
388+
.build())
389+
.build();
390+
}
373391
}

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

+100
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
import io.qdrant.client.grpc.Collections.AliasOperations;
2424
import io.qdrant.client.grpc.Collections.ChangeAliases;
2525
import io.qdrant.client.grpc.Collections.CollectionDescription;
26+
import io.qdrant.client.grpc.Collections.CollectionExistsRequest;
27+
import io.qdrant.client.grpc.Collections.CollectionExistsResponse;
2628
import io.qdrant.client.grpc.Collections.CollectionInfo;
2729
import io.qdrant.client.grpc.Collections.CollectionOperationResponse;
2830
import io.qdrant.client.grpc.Collections.CreateAlias;
@@ -476,6 +478,33 @@ public ListenableFuture<CollectionOperationResponse> updateCollectionAsync(Updat
476478
}, MoreExecutors.directExecutor());
477479
}
478480

481+
/**
482+
* Check if a collection exists
483+
*
484+
* @param collectionName The name of the collection.
485+
* @return a new instance of {@link ListenableFuture}
486+
*/
487+
public ListenableFuture<Boolean> collectionExistsAsync(String collectionName) {
488+
return collectionExistsAsync(collectionName, null);
489+
}
490+
491+
/**
492+
* Check if a collection exists
493+
*
494+
* @param collectionName The name of the collection.
495+
* @param timeout The timeout for the call.
496+
* @return a new instance of {@link ListenableFuture}
497+
*/
498+
public ListenableFuture<Boolean> collectionExistsAsync(String collectionName, @Nullable Duration timeout) {
499+
Preconditions.checkArgument(!collectionName.isEmpty(), "Collection name must not be empty");
500+
logger.debug("Collection exists '{}'", collectionName);
501+
502+
ListenableFuture<CollectionExistsResponse> future = getCollections(timeout)
503+
.collectionExists(CollectionExistsRequest.newBuilder().setCollectionName(collectionName).build());
504+
addLogFailureCallback(future, "Collection exists");
505+
return Futures.transform(future, response -> response.getResult().getExists(), MoreExecutors.directExecutor());
506+
}
507+
479508
//endregion
480509

481510
//region Alias Management
@@ -1515,6 +1544,38 @@ public ListenableFuture<UpdateResult> setPayloadAsync(
15151544
@Nullable Boolean wait,
15161545
@Nullable WriteOrderingType ordering,
15171546
@Nullable Duration timeout
1547+
) {
1548+
return setPayloadAsync(
1549+
collectionName,
1550+
payload,
1551+
pointsSelector,
1552+
wait,
1553+
null,
1554+
ordering,
1555+
timeout
1556+
);
1557+
}
1558+
1559+
/**
1560+
* Sets the payload for the points.
1561+
*
1562+
* @param collectionName The name of the collection.
1563+
* @param payload New payload values
1564+
* @param pointsSelector Selector for the points whose payloads are to be set.
1565+
* @param wait Whether to wait until the changes have been applied. Defaults to <code>true</code>.
1566+
* @param key The key for which to set the payload if nested
1567+
* @param ordering Write ordering guarantees.
1568+
* @param timeout The timeout for the call.
1569+
* @return a new instance of {@link ListenableFuture}
1570+
*/
1571+
public ListenableFuture<UpdateResult> setPayloadAsync(
1572+
String collectionName,
1573+
Map<String, Value> payload,
1574+
@Nullable PointsSelector pointsSelector,
1575+
@Nullable Boolean wait,
1576+
@Nullable String key,
1577+
@Nullable WriteOrderingType ordering,
1578+
@Nullable Duration timeout
15181579
) {
15191580
SetPayloadPoints.Builder requestBuilder = SetPayloadPoints.newBuilder()
15201581
.setCollectionName(collectionName)
@@ -1529,6 +1590,10 @@ public ListenableFuture<UpdateResult> setPayloadAsync(
15291590
requestBuilder.setOrdering(WriteOrdering.newBuilder().setType(ordering).build());
15301591
}
15311592

1593+
if (key != null) {
1594+
requestBuilder.setKey(key);
1595+
}
1596+
15321597
return setPayloadAsync(requestBuilder.build(), timeout);
15331598
}
15341599

@@ -1687,6 +1752,38 @@ public ListenableFuture<UpdateResult> overwritePayloadAsync(
16871752
@Nullable Boolean wait,
16881753
@Nullable WriteOrderingType ordering,
16891754
@Nullable Duration timeout
1755+
) {
1756+
return overwritePayloadAsync(
1757+
collectionName,
1758+
payload,
1759+
pointsSelector,
1760+
wait,
1761+
null,
1762+
ordering,
1763+
timeout
1764+
);
1765+
}
1766+
1767+
/**
1768+
* Overwrites the payload for the points.
1769+
*
1770+
* @param collectionName The name of the collection.
1771+
* @param payload New payload values
1772+
* @param pointsSelector Selector for the points whose payloads are to be overwritten.
1773+
* @param wait Whether to wait until the changes have been applied. Defaults to <code>true</code>.
1774+
* @param key The key for which to overwrite the payload if nested
1775+
* @param ordering Write ordering guarantees.
1776+
* @param timeout The timeout for the call.
1777+
* @return a new instance of {@link ListenableFuture}
1778+
*/
1779+
public ListenableFuture<UpdateResult> overwritePayloadAsync(
1780+
String collectionName,
1781+
Map<String, Value> payload,
1782+
@Nullable PointsSelector pointsSelector,
1783+
@Nullable Boolean wait,
1784+
@Nullable String key,
1785+
@Nullable WriteOrderingType ordering,
1786+
@Nullable Duration timeout
16901787
) {
16911788
SetPayloadPoints.Builder requestBuilder = SetPayloadPoints.newBuilder()
16921789
.setCollectionName(collectionName)
@@ -1701,6 +1798,9 @@ public ListenableFuture<UpdateResult> overwritePayloadAsync(
17011798
requestBuilder.setOrdering(WriteOrdering.newBuilder().setType(ordering).build());
17021799
}
17031800

1801+
if (key != null)
1802+
requestBuilder.setKey(key);
1803+
17041804
return overwritePayloadAsync(requestBuilder.build(), timeout);
17051805
}
17061806

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package io.qdrant.client;
2+
3+
import java.time.Instant;
4+
5+
import com.google.protobuf.Timestamp;
6+
7+
import io.qdrant.client.grpc.Points.StartFrom;
8+
9+
/**
10+
* Convenience methods for constructing {@link StartFrom}
11+
*/
12+
public final class StartFromFactory {
13+
private StartFromFactory() {
14+
}
15+
16+
/**
17+
* Creates a {@link StartFrom} value from a {@link float}
18+
*
19+
* @param value The value
20+
* @return a new instance of {@link StartFrom}
21+
*/
22+
public static StartFrom startFrom(float value) {
23+
return StartFrom.newBuilder().setFloat(value).build();
24+
}
25+
26+
/**
27+
* Creates a {@link StartFrom} value from a {@link int}
28+
*
29+
* @param value The value
30+
* @return a new instance of {@link StartFrom}
31+
*/
32+
public static StartFrom startFrom(int value) {
33+
return StartFrom.newBuilder().setInteger(value).build();
34+
}
35+
36+
/**
37+
* Creates a {@link StartFrom} value from a {@link String} timestamp
38+
*
39+
* @param value The value
40+
* @return a new instance of {@link StartFrom}
41+
*/
42+
public static StartFrom startFrom(String value) {
43+
return StartFrom.newBuilder().setDatetime(value).build();
44+
}
45+
46+
/**
47+
* Creates a {@link StartFrom} value from a {@link Timestamp}
48+
*
49+
* @param value The value
50+
* @return a new instance of {@link StartFrom}
51+
*/
52+
public static StartFrom startFrom(Timestamp value) {
53+
return StartFrom.newBuilder().setTimestamp(value).build();
54+
}
55+
56+
/**
57+
* Creates a {@link StartFrom} value from a {@link Timestamp}
58+
*
59+
* @param value The value
60+
* @return a new instance of {@link StartFrom}
61+
*/
62+
public static StartFrom startFrom(Instant value) {
63+
return StartFrom.newBuilder().setTimestamp(Timestamp.newBuilder().setSeconds(value.getEpochSecond())).build();
64+
}
65+
}

src/test/java/io/qdrant/client/CollectionsTest.java

+13
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package io.qdrant.client;
22

33
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
import static org.junit.jupiter.api.Assertions.assertFalse;
45
import static org.junit.jupiter.api.Assertions.assertThrows;
56
import static org.junit.jupiter.api.Assertions.assertTrue;
67

@@ -180,6 +181,18 @@ public void getCollectionInfo_with_missing_collection() {
180181
assertEquals(Status.Code.NOT_FOUND, underlyingException.getStatus().getCode());
181182
}
182183

184+
@Test
185+
public void collectionExists() throws ExecutionException, InterruptedException {
186+
assertFalse(client.collectionExistsAsync(testName).get());
187+
188+
CreateCollection createCollection = getCreateCollection(testName);
189+
client.createCollectionAsync(createCollection).get();
190+
assertTrue(client.collectionExistsAsync(testName).get());
191+
192+
client.deleteCollectionAsync(testName).get();
193+
assertFalse(client.collectionExistsAsync(testName).get());
194+
}
195+
183196
@Test
184197
public void createAlias() throws ExecutionException, InterruptedException {
185198
CreateCollection createCollection = getCreateCollection(testName);

0 commit comments

Comments
 (0)