From 0f6b68bf2d7359f55517e982ae745f982fb20827 Mon Sep 17 00:00:00 2001 From: Russ Cam Date: Tue, 12 Dec 2023 22:10:38 +1000 Subject: [PATCH] Update README --- README.md | 192 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 106 insertions(+), 86 deletions(-) diff --git a/README.md b/README.md index 12b4950c..2c8757c5 100644 --- a/README.md +++ b/README.md @@ -31,133 +31,153 @@ Java client library with handy utility methods and overloads for interfacing wit To install the library, add the following lines to your build config file. #### Maven + ```xml io.qdrant client - 1.0 + 1.7-SNAPSHOT ``` #### Scala SBT + ```sbt -libraryDependencies += "io.qdrant" % "client" % "1.0" +libraryDependencies += "io.qdrant" % "client" % "1.7-SNAPSHOT" ``` #### Gradle + ```gradle -implementation 'io.qdrant:client:1.0' +implementation 'io.qdrant:client:1.7-SNAPSHOT' ``` ## ๐Ÿ“– Documentation + - [`QdrantClient` Reference](https://qdrant.github.io/java-client/io/qdrant/client/QdrantClient.html#constructor-detail) -- [Utility Methods Reference](https://qdrant.github.io/java-client/io/qdrant/client/utils/package-summary.html) -## ๐Ÿ”Œ Connecting to Qdrant +## ๐Ÿ”Œ Getting started -> [!NOTE] -> The library uses Qdrant's GRPC interface. The default port being `6334`. -> -> Uses `TLS` if the URL protocol is `https`, plaintext otherwise. +### Creating a client -#### Connecting to a local Qdrant instance -```java -import io.qdrant.client.QdrantClient; +A client can be instantiated with -QdrantClient client = new QdrantClient("http://localhost:6334"); +```java +QdrantClient client = + new QdrantClient(QdrantGrpcClient.newBuilder("localhost").build()); ``` +which creates a client that will connect to Qdrant on https://localhost:6334. -#### Connecting to Qdrant cloud -```java -import io.qdrant.client.QdrantClient; +Internally, the high level client uses a low level gRPC client to interact with +Qdrant. Additional constructor overloads provide more control over how the gRPC +client is configured. The following example configures a client to use TLS, +validating the certificate using the root CA to verify the server's identity +instead of the system's default, and also configures API key authentication: -QdrantClient client = new QdrantClient("https://xyz-eg.eu-central.aws.cloud.qdrant.io:6334", ""); +```java +ManagedChannel channel = Grpc.newChannelBuilder( + "localhost:6334", + TlsChannelCredentials.newBuilder() + .trustManager(new File("ssl/ca.crt")) + .build()) +.build(); + +QdrantClient client = new QdrantClient( + QdrantGrpcClient.newBuilder(channel) + .withApiKey("") + .build()); ``` -## ๐Ÿงช Example Usage -
-Click to expand example - +The client implements [`AutoCloseable`](https://docs.oracle.com/javase/8/docs/api/java/lang/AutoCloseable.html), +though a client will typically be created once and used for the lifetime of the +application. When a client is constructed by passing a `ManagedChannel`, the +client does not shut down the channel on close by default. The client can be +configured to shut down the channel on close with -#### You can connect to Qdrant by instantiating a [QdrantClient](https://qdrant.github.io/java-client/io/qdrant/client/QdrantClient.html) instance. ```java -import io.qdrant.client.QdrantClient; +ManagedChannel channel = Grpc.newChannelBuilder( + "localhost:6334", + TlsChannelCredentials.create()) +.build(); + +QdrantClient client = new QdrantClient( + QdrantGrpcClient.newBuilder(channel, true) + .withApiKey("") + .build()); +``` -QdrantClient client = new QdrantClient("http://localhost:6334"); +All client methods return `ListenableFuture`. -System.out.println(client.listCollections()); -``` -*Output*: -``` -collections { -name: "Documents" -} -collections { -name: "some_collection" -} -time: 7.04541E-4 -``` +### Working with collections -#### We can now perform operations on the DB. Like creating a collection, adding a point. -The library offers handy utility methods for constructing GRPC structures. +Once a client has been created, create a new collection ```java -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import io.qdrant.client.utils.*; +client.createCollectionAsync("my_collection", + VectorParams.newBuilder() + .setDistance(Distance.Cosine) + .setSize(4) + .build()) + .get(); +``` -String collectionName = "Documents"; +Insert vectors into a collection -client.recreateCollection(collectionName, 6, Distance.Cosine); +```java +// import static convenience methods +import static io.qdrant.client.PointIdFactory.id; +import static io.qdrant.client.ValueFactory.value; +import static io.qdrant.client.VectorsFactory.vector; + +Random random = new Random(); +List points = IntStream.range(1, 101) + .mapToObj(i -> PointStruct.newBuilder() + .setId(id(i)) + .setVectors(vector(IntStream.range(1, 101) + .mapToObj(v -> random.nextFloat()) + .collect(Collectors.toList()))) + .putAllPayload(ImmutableMap.of( + "color", value("red"), + "rand_number", value(i % 10)) + ) + .build() + ) + .collect(Collectors.toList()); + +UpdateResult updateResult = client.upsertAsync("my_collection", points).get(); +``` -Map map = new HashMap<>(); -map.put("name", "John Doe"); -map.put("age", 42); -map.put("married", true); +Search for similar vectors -PointStruct point = - PointUtil.point( - 0, - VectorUtil.toVector(0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f), - PayloadUtil.toPayload(map)); -List points = Arrays.asList(point); -client.upsertPoints(collectionName, points, null); +```java +List queryVector = IntStream.range(1, 101) + .mapToObj(v -> random.nextFloat()) + .collect(Collectors.toList()); + +List points = client.searchAsync(SearchPoints.newBuilder() + .setCollectionName("my_collection") + .addAllVector(queryVector) + .setLimit(5) + .build() +).get(); ``` -#### Performing a search on the vectors with filtering +Search for similar vectors with filtering condition + ```java -import io.qdrant.client.grpc.Points.Filter; -import io.qdrant.client.grpc.Points.SearchPoints; -import io.qdrant.client.grpc.Points.SearchResponse; - -import io.qdrant.client.utils.*; - -Filter filter = FilterUtil.must(FilterUtil.fieldCondition("age", FilterUtil.match(42))); - -SearchPoints request = SearchPoints.newBuilder() - .setCollectionName(collectionName) - .addAllVector(Arrays.asList(0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f)) - .setFilter(filter) - .setWithPayload(SelectorUtil.withPayload()) - .setLimit(10) - .build(); -SearchResponse result = client.searchPoints(request); - -ScoredPoint result = results.getResult(0); - -System.out.println("Similarity: " + result.getScore()); -System.out.println("Payload: " + PayloadUtil.toMap(result.getPayload())); -``` -*Output*: +// import static convenience methods +import static io.qdrant.client.ConditionFactory.range; + +List points = client.searchAsync(SearchPoints.newBuilder() + .setCollectionName("my_collection") + .addAllVector(queryVector) + .setFilter(Filter.newBuilder() + .addMust(range("rand_number", Range.newBuilder().setGte(3).build())) + .build()) + .setLimit(5) + .build() +).get(); ``` -Similarity: 0.9999999 -Payload: {name=John Doe, married=true, age=42} -``` - -
## โš–๏ธ LICENSE