Skip to content

Commit

Permalink
Update docs, add jreleaser
Browse files Browse the repository at this point in the history
  • Loading branch information
Jotschi committed Feb 2, 2023
1 parent 6f90531 commit 110c683
Show file tree
Hide file tree
Showing 16 changed files with 250 additions and 103 deletions.
133 changes: 75 additions & 58 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ This project contains a java client for the [Qdrant vector database](https://qdr
<dependency>
<groupId>io.metaloom.qdrant</groupId>
<artifactId>qdrant-java-grpc-client</artifactId>
<version>0.0.1-SNAPSHOT</version>
<version>0.9.0-SNAPSHOT</version>
</dependency>
```

Expand All @@ -46,7 +46,7 @@ or for the HTTP client
<dependency>
<groupId>io.metaloom.qdrant</groupId>
<artifactId>qdrant-java-http-client</artifactId>
<version>0.0.1-SNAPSHOT</version>
<version>0.9.0-SNAPSHOT</version>
</dependency>
```

Expand All @@ -62,70 +62,87 @@ This client was build and tested for Qdrant server version `v0.11.7`. Minimum re
## Usage - gRPC

```java
QDrantGRPCClient client = QDrantGRPCClient.builder()
.setHostname("localhost")
.setPort(qdrant.grpcPort())
try (QDrantGRPCClient client = QDrantGRPCClient.builder()
.setHostname("localhost")
.setPort(port)
.build()) {

// Define the collection to store vectors
VectorParams params = VectorParams.newBuilder()
.setSize(4)
.setDistance(Distance.Euclid)
.build();

VectorParams params = VectorParams.newBuilder()
.setSize(4)
.setDistance(Distance.Euclid)
.build();

// Create new collections - blocking
client.createCollection("test1", params).blocking().getResult();
// Or using Future API
client.createCollection("test2", params).future().get().getResult();
// Or using RxJava API
client.createCollection("test3", params).rx().blockingGet().getResult();


// Insert a new vector
for (int i = 0; i < 10; i++) {
Vector vector = ModelHelper.toVector(new float[] { 0.43f + i, 0.1f, 0.61f, 1.45f });
PointStruct point = PointStruct.newBuilder()
.putPayload("color", ModelHelper.toValue("blue"))
.setId(ModelHelper.toPointId(42L + i))
.setVectors(Vectors.newBuilder().setVector(vector))
.build();
System.out.println(client.upsertPoint("test1", point, true).blocking().getResult().getStatus());
// Create new collections - blocking
client.createCollection("test1", params).sync();
// .. or via Future API
client.createCollection("test2", params).async().get();
// .. or via RxJava API
client.createCollection("test3", params).rx().blockingGet();

// Insert a new vectors
for (int i = 0; i < 10; i++) {

// Vector of the point
float[] vector = new float[] { 0.43f + i, 0.1f, 0.61f, 1.45f - i };

// Payload of the point
Map<String, Value> payload = new HashMap<>();
payload.put("color", ModelHelper.value("blue"));

// Now construct the point
PointStruct point = ModelHelper.point(42L + i, vector, payload);
// .. and insert it
client.upsertPoint("test1", point, true).sync();
}

// Count points
long nPoints = client.countPoints("test1", null, true).sync().getResult().getCount();

// Now run KNN search
float[] searchVector = new float[] { 0.43f, 0.09f, 0.41f, 1.35f };
List<ScoredPoint> searchResults = client.searchPoints("test1", searchVector, 2, null).sync().getResultList();
for (ScoredPoint result : searchResults) {
System.out.println("Found: [" + result.getId().getNum() + "] " + result.getScore());
}

// Invoke backup via Snapshot API
client.createSnapshot("test1").sync();
}

// Count vectors
client.countPoints("test1", null, true).blocking().getResult().getCount();
```


## Usage - HTTP

```java
QDrantHttpClient client = QDrantHttpClient.builder()
try (QDrantHttpClient client = QDrantHttpClient.builder()
.setHostname("localhost")
.setPort(qdrant.httpPort())
.build();

// Create a collection
CollectionCreateRequest req = new CollectionCreateRequest();
req.setVectors("colors", 4, Distance.EUCLID);
client.createCollection("the-collection-name", req).sync();

// Now add some points
PointStruct p1 = PointStruct.of("colors", 0.42f, 0.33f, 42.15f, 68.72f)
.setPayload("{\"name\": \"first\"}")
.setId(1);
PointStruct p2 = PointStruct.of("colors", 0.76f, 0.43f, 63.45f, 22.10f)
.setPayload("{ \"color\": \"red\"}")
.setId(2);
PointStruct p3 = PointStruct.of("colors", 0.41f, 0.32f, 42.11f, 68.71f).setId(3);
PointStruct p4 = PointStruct.of("colors", 0.12f, 0.23f, 12.46f, 47.17f).setId(4);

PointsListUpsertRequest pointsRequest = new PointsListUpsertRequest();
pointsRequest.setPoints(p1, p2, p3, p4);
client.upsertPoints("the-collection-name", pointsRequest, false).async().blockingGet();

// List the collections
client.listCollections().async().blockingGet();

// Count the points in the collection
client.countPoints("the-collection-name", new PointCountRequest().setExact(true)).sync();
.setPort(port)
.build()) {

// Create a collection
CollectionCreateRequest req = new CollectionCreateRequest();
req.setVectors("colors", 4, Distance.EUCLID);
client.createCollection("the-collection-name", req).sync();

// Now add some points
PointStruct p1 = PointStruct.of("colors", 0.42f, 0.33f, 42.15f, 68.72f)
.setPayload("{\"name\": \"first\"}")
.setId(1);
PointStruct p2 = PointStruct.of("colors", 0.76f, 0.43f, 63.45f, 22.10f)
.setPayload("{ \"color\": \"red\"}")
.setId(2);
PointStruct p3 = PointStruct.of("colors", 0.41f, 0.32f, 42.11f, 68.71f).setId(3);
PointStruct p4 = PointStruct.of("colors", 0.12f, 0.23f, 12.46f, 47.17f).setId(4);

PointsListUpsertRequest pointsRequest = new PointsListUpsertRequest();
pointsRequest.setPoints(p1, p2, p3, p4);
client.upsertPoints("the-collection-name", pointsRequest, false).async().blockingGet();

// List the collections
client.listCollections().async().blockingGet();

// Count the points in the collection
client.countPoints("the-collection-name", new PointCountRequest().setExact(true)).sync();
}
```
2 changes: 1 addition & 1 deletion common/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<parent>
<groupId>io.metaloom.qdrant</groupId>
<artifactId>qdrant-java-client</artifactId>
<version>0.0.1-SNAPSHOT</version>
<version>0.9.0-SNAPSHOT</version>
</parent>

<name>Qdrant Java Client :: common</name>
Expand Down
2 changes: 1 addition & 1 deletion grpc/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<parent>
<groupId>io.metaloom.qdrant</groupId>
<artifactId>qdrant-java-client</artifactId>
<version>0.0.1-SNAPSHOT</version>
<version>0.9.0-SNAPSHOT</version>
</parent>

<name>Qdrant Java Client :: grpc</name>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@
import io.metaloom.qdrant.client.grpc.proto.RaftGrpc;
import io.metaloom.qdrant.client.grpc.proto.SnapshotsGrpc;

public final class GrpcUtil {
public final class InternalGrpcUtil {

private InternalGrpcUtil() {
}

public static CollectionsGrpc.CollectionsBlockingStub collectionsStub(ClientSettings client) {
return CollectionsGrpc.newBlockingStub(client.channel());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package io.metaloom.qdrant.client.grpc.method;

import static io.metaloom.qdrant.client.grpc.GrpcUtil.collectionsAsyncStub;
import static io.metaloom.qdrant.client.grpc.GrpcUtil.collectionsStub;
import static io.metaloom.qdrant.client.grpc.InternalGrpcUtil.collectionsAsyncStub;
import static io.metaloom.qdrant.client.grpc.InternalGrpcUtil.collectionsStub;

import java.util.List;
import java.util.Objects;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,34 @@ public class GrpcClientRequest<T> {
private final ClientSettings settings;

public GrpcClientRequest(ClientSettings settings, Supplier<T> blockingSupplier, Supplier<ListenableFuture<T>> asyncSupplier) {
this.settings= settings;
this.settings = settings;
this.blocking = blockingSupplier;
this.async = asyncSupplier;
}

/**
* Execute the request synchronously / blocking.
*
* @return
*/
public T sync() {
return blocking.get();
}

/**
* Execute the request asynchronously.
*
* @return
*/
public ListenableFuture<T> async() {
return async.get();
}

/**
* Execute the the request asynchronously via RxJava.
*
* @return
*/
public Maybe<T> rx() {
return QDrantClientUtil.toMaybe(async(), settings);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package io.metaloom.qdrant.client.grpc.method;

import static io.metaloom.qdrant.client.grpc.GrpcUtil.pointsAsyncStub;
import static io.metaloom.qdrant.client.grpc.GrpcUtil.pointsStub;
import static io.metaloom.qdrant.client.grpc.InternalGrpcUtil.pointsAsyncStub;
import static io.metaloom.qdrant.client.grpc.InternalGrpcUtil.pointsStub;

import java.util.Arrays;
import java.util.List;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package io.metaloom.qdrant.client.grpc.method;

import static io.metaloom.qdrant.client.grpc.GrpcUtil.pointsAsyncStub;
import static io.metaloom.qdrant.client.grpc.GrpcUtil.pointsStub;
import static io.metaloom.qdrant.client.grpc.InternalGrpcUtil.pointsAsyncStub;
import static io.metaloom.qdrant.client.grpc.InternalGrpcUtil.pointsStub;

import java.util.ArrayList;
import java.util.List;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package io.metaloom.qdrant.client.grpc.method;

import static io.metaloom.qdrant.client.grpc.GrpcUtil.snapshotsAsyncStub;
import static io.metaloom.qdrant.client.grpc.GrpcUtil.snapshotsStub;
import static io.metaloom.qdrant.client.grpc.InternalGrpcUtil.snapshotsAsyncStub;
import static io.metaloom.qdrant.client.grpc.InternalGrpcUtil.snapshotsStub;

import java.util.Objects;

Expand Down
50 changes: 38 additions & 12 deletions grpc/src/main/java/io/metaloom/qdrant/client/util/ModelHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,37 +55,63 @@ public static PointId pointId(long id) {
return PointId.newBuilder().setNum(id).build();
}

/**
* Construct a {@link PointId} from the provided uuid.
*
* @param uuid
* @return
*/
public static PointId pointId(UUID uuid) {
Objects.requireNonNull(uuid, "The provided uuid must not be null");
return PointId.newBuilder().setUuid(uuid.toString()).build();
}

/**
* Construct a {@link PointId} from the provided uuid string.
*
* @param uuid
* @return
*/
public static PointId pointId(String uuid) {
Objects.requireNonNull(uuid, "The provided uuid must not be null");
return PointId.newBuilder().setUuid(UUID.fromString(uuid).toString()).build();
}

/**
* Create a list of {@link PointId}d
*
* @param ids
* @return
*/
public static List<PointId> pointIds(long... ids) {
List<PointId> list = new ArrayList<>();
for (long id : ids) {
list.add(pointId(id));
}
return list;
}

public static PointStruct point(String uuid, float[] vectorData, Map<String, Value> payload) {
return toPointStruct(pointId(uuid), vectorData, payload);
return point(pointId(uuid), vectorData, payload);
}

public static PointStruct point(UUID uuid, float[] vectorData, Map<String, Value> payload) {
return toPointStruct(pointId(uuid), vectorData, payload);
return point(pointId(uuid), vectorData, payload);
}

public static PointStruct point(long id, float[] vectorData, Map<String, Value> payload) {
return toPointStruct(pointId(id), vectorData, payload);
}

public static List<PointId> pointIds(long... ids) {
List<PointId> list = new ArrayList<>();
for (long id : ids) {
list.add(pointId(id));
}
return list;
return point(pointId(id), vectorData, payload);
}

public static PointStruct toPointStruct(PointId id, float[] vectorData, Map<String, Value> payload) {
/**
* Construct a new {@link PointStruct} using the provided data.
*
* @param id
* @param vectorData
* @param payload
* @return
*/
public static PointStruct point(PointId id, float[] vectorData, Map<String, Value> payload) {
Objects.requireNonNull(id, "A pointId must be provided.");
Vector vector = ModelHelper.vector(vectorData);
Builder builder = PointStruct.newBuilder()
Expand Down
Loading

0 comments on commit 110c683

Please sign in to comment.