From 8ebaadf9ac2010a93b52baadd512efbc6d5cd7ea Mon Sep 17 00:00:00 2001 From: generall Date: Mon, 18 Aug 2025 23:53:26 +0200 Subject: [PATCH 1/3] add example project for testing snippets --- example/.dockerignore | 8 +++ example/Dockerfile | 35 +++++++++++++ example/README.md | 23 ++++++++ example/build-and-run.sh | 5 ++ example/build.gradle | 52 +++++++++++++++++++ example/gradle.properties | 3 ++ .../java/io/qdrant/example/QdrantExample.java | 52 +++++++++++++++++++ 7 files changed, 178 insertions(+) create mode 100644 example/.dockerignore create mode 100644 example/Dockerfile create mode 100644 example/README.md create mode 100644 example/build-and-run.sh create mode 100644 example/build.gradle create mode 100644 example/gradle.properties create mode 100644 example/src/main/java/io/qdrant/example/QdrantExample.java diff --git a/example/.dockerignore b/example/.dockerignore new file mode 100644 index 00000000..50a2800e --- /dev/null +++ b/example/.dockerignore @@ -0,0 +1,8 @@ +.git +.gradle +build/ +!build/libs/*.jar +*.md +gradlew +gradlew.bat +gradle/ diff --git a/example/Dockerfile b/example/Dockerfile new file mode 100644 index 00000000..c9e35785 --- /dev/null +++ b/example/Dockerfile @@ -0,0 +1,35 @@ +# Use OpenJDK 11 as base image +FROM openjdk:11-jdk-slim AS build + +# Set working directory +WORKDIR /app + +# Install Gradle +RUN apt-get update && \ + apt-get install -y wget unzip && \ + wget https://services.gradle.org/distributions/gradle-8.4-bin.zip && \ + unzip gradle-8.4-bin.zip && \ + rm gradle-8.4-bin.zip && \ + mv gradle-8.4 /opt/gradle && \ + ln -s /opt/gradle/bin/gradle /usr/local/bin/gradle && \ + apt-get remove -y wget unzip && \ + apt-get autoremove -y && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +# Copy source code and build files +COPY . . + +# Build the application fat jar +RUN gradle --no-daemon clean shadowJar + +# Create a runtime image +FROM openjdk:11-jre-slim + +WORKDIR /app + +# Copy the built JAR from the build stage (versioned shaded jar) +COPY --from=build /app/build/libs/app-*-all.jar /app/app.jar + +# Set the entrypoint +ENTRYPOINT ["java", "-jar", "app.jar"] diff --git a/example/README.md b/example/README.md new file mode 100644 index 00000000..9239215f --- /dev/null +++ b/example/README.md @@ -0,0 +1,23 @@ +# Simple Qdrant Client Example + +This is a simple Java application that demonstrates how to interact with a Qdrant vector database server using the official Qdrant Java client. + +## Prerequisites + +- Docker installed on your system + +## Quick Start + +### 1. Start Qdrant + +First, make sure Qdrant is running. You can start it with Docker: + +```bash +docker run --rm -it -p 6334:6334 -p 6333:6333 qdrant/qdrant +``` + +### 2. Building and Running + +```bash +bash -x build-and-run.sh +``` diff --git a/example/build-and-run.sh b/example/build-and-run.sh new file mode 100644 index 00000000..0d99a91b --- /dev/null +++ b/example/build-and-run.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +docker build -t qdrant-simple-example . + +docker run --rm -it --network host qdrant-simple-example diff --git a/example/build.gradle b/example/build.gradle new file mode 100644 index 00000000..4298fec2 --- /dev/null +++ b/example/build.gradle @@ -0,0 +1,52 @@ +plugins { + id 'java' + id 'application' + id 'com.github.johnrengelman.shadow' version '8.1.1' +} + +group = 'io.qdrant.example' +version = '1.0.0' + +repositories { + mavenCentral() +} + +dependencies { + // Qdrant Java client + implementation 'io.qdrant:client:1.15.0' + + // gRPC dependencies - use the same version as Qdrant client + implementation 'io.grpc:grpc-netty-shaded:1.65.1' + implementation 'io.grpc:grpc-protobuf:1.65.1' + implementation 'io.grpc:grpc-stub:1.65.1' + implementation 'io.grpc:grpc-services:1.65.1' + + // Protobuf runtime + implementation 'com.google.protobuf:protobuf-java:3.25.4' + + // Logging + implementation 'org.slf4j:slf4j-simple:2.0.14' +} + +application { + mainClass = 'io.qdrant.example.QdrantExample' +} + +java { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 +} + +// Create a proper fat jar and merge service descriptor files (required by gRPC) +shadowJar { + mergeServiceFiles() + archiveBaseName.set('app') + archiveClassifier.set('all') +} + +// Keep the plain jar minimal (no dependency unpacking) +jar { + manifest { + attributes 'Main-Class': 'io.qdrant.example.QdrantExample' + } +} diff --git a/example/gradle.properties b/example/gradle.properties new file mode 100644 index 00000000..8c838a5c --- /dev/null +++ b/example/gradle.properties @@ -0,0 +1,3 @@ +org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 +org.gradle.parallel=true +org.gradle.caching=true diff --git a/example/src/main/java/io/qdrant/example/QdrantExample.java b/example/src/main/java/io/qdrant/example/QdrantExample.java new file mode 100644 index 00000000..43cc35a2 --- /dev/null +++ b/example/src/main/java/io/qdrant/example/QdrantExample.java @@ -0,0 +1,52 @@ +package io.qdrant.example; + +import io.grpc.Grpc; +import io.grpc.InsecureChannelCredentials; +import io.grpc.ManagedChannel; +import io.qdrant.client.QdrantClient; +import io.qdrant.client.QdrantGrpcClient; +import io.qdrant.client.grpc.Collections; +import io.qdrant.client.grpc.Collections.CreateCollection; +import io.qdrant.client.grpc.Collections.VectorParams; +import io.qdrant.client.grpc.Collections.Distance; +import java.util.List; +import java.util.concurrent.ExecutionException; + +public class QdrantExample { + public static void main(String[] args) { + try { + ManagedChannel channel = + Grpc.newChannelBuilder( + "localhost:6334", InsecureChannelCredentials.create()) + .build(); + QdrantGrpcClient grpcClient = QdrantGrpcClient.newBuilder(channel, true).build(); + QdrantClient client = new QdrantClient(grpcClient); + + + // Create a simple collection + String collectionName = "example_collection"; + + client.createCollectionAsync( + collectionName, + VectorParams.newBuilder() + .setDistance(Distance.Cosine) + .setSize(128) + .build() + ).get(); + + + List collections = client.listCollectionsAsync().get(); + + for (String collection : collections) { + System.out.println("- " + collection); + } + + client.close(); + + } catch (Exception e) { + System.err.println("Error occurred: " + e.getMessage()); + e.printStackTrace(); + System.exit(1); + } + } +} From 95f4e5540aea4e16a10b1f9c6f7cdb4a1702d4cf Mon Sep 17 00:00:00 2001 From: Anush008 Date: Tue, 19 Aug 2025 10:29:45 +0530 Subject: [PATCH 2/3] chore: Simplified client instantiation Signed-off-by: Anush008 --- .../java/io/qdrant/example/QdrantExample.java | 35 +++++++------------ 1 file changed, 13 insertions(+), 22 deletions(-) diff --git a/example/src/main/java/io/qdrant/example/QdrantExample.java b/example/src/main/java/io/qdrant/example/QdrantExample.java index 43cc35a2..30a9515c 100644 --- a/example/src/main/java/io/qdrant/example/QdrantExample.java +++ b/example/src/main/java/io/qdrant/example/QdrantExample.java @@ -1,39 +1,30 @@ package io.qdrant.example; -import io.grpc.Grpc; -import io.grpc.InsecureChannelCredentials; -import io.grpc.ManagedChannel; import io.qdrant.client.QdrantClient; import io.qdrant.client.QdrantGrpcClient; -import io.qdrant.client.grpc.Collections; -import io.qdrant.client.grpc.Collections.CreateCollection; import io.qdrant.client.grpc.Collections.VectorParams; import io.qdrant.client.grpc.Collections.Distance; import java.util.List; -import java.util.concurrent.ExecutionException; public class QdrantExample { public static void main(String[] args) { try { - ManagedChannel channel = - Grpc.newChannelBuilder( - "localhost:6334", InsecureChannelCredentials.create()) - .build(); - QdrantGrpcClient grpcClient = QdrantGrpcClient.newBuilder(channel, true).build(); - QdrantClient client = new QdrantClient(grpcClient); + QdrantClient client = new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false) + .build()); + - // Create a simple collection String collectionName = "example_collection"; - - client.createCollectionAsync( - collectionName, - VectorParams.newBuilder() - .setDistance(Distance.Cosine) - .setSize(128) - .build() - ).get(); - + + if (!client.collectionExistsAsync(collectionName).get()) { + client.createCollectionAsync( + collectionName, + VectorParams.newBuilder() + .setDistance(Distance.Cosine) + .setSize(128) + .build() + ).get(); + } List collections = client.listCollectionsAsync().get(); From 99a021d64fa67062b28ff38061fd6fe6b36335e5 Mon Sep 17 00:00:00 2001 From: generall Date: Tue, 19 Aug 2025 11:31:53 +0200 Subject: [PATCH 3/3] simplify connection --- example/src/main/java/io/qdrant/example/QdrantExample.java | 1 - 1 file changed, 1 deletion(-) diff --git a/example/src/main/java/io/qdrant/example/QdrantExample.java b/example/src/main/java/io/qdrant/example/QdrantExample.java index 30a9515c..2c12ca4e 100644 --- a/example/src/main/java/io/qdrant/example/QdrantExample.java +++ b/example/src/main/java/io/qdrant/example/QdrantExample.java @@ -12,7 +12,6 @@ public static void main(String[] args) { QdrantClient client = new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false) .build()); - // Create a simple collection String collectionName = "example_collection";