diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index f122d22..15d39a2 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -17,10 +17,10 @@ jobs: steps: - name: Checkout - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 + uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0 - name: Set up JDK 21 - uses: actions/setup-java@ad2b38190b15e4d6bdf0c97fb4fca8412226d287 # v5.3.0 + uses: actions/setup-java@03ad4de0992f5dab5e18fcb136590ce7c4a0ac95 # v5.6.0 with: java-version: '21' distribution: 'temurin' @@ -41,7 +41,7 @@ jobs: arguments: test --info - name: Test Results - uses: mikepenz/action-junit-report@3a81627bfac62268172037048872e8ebd4207e6d # v6.4.1 + uses: mikepenz/action-junit-report@d9f48fc87bc235f7e214acf696ca5abc0a986f16 # v6.4.2 if: always() with: fail_on_failure: true @@ -65,10 +65,10 @@ jobs: ORG_GRADLE_PROJECT_sonatypePassword: ${{ secrets.ORG_GRADLE_PROJECT_SONATYPEPASSWORD }} steps: - name: Checkout - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 + uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0 - name: Set up JDK 21 - uses: actions/setup-java@ad2b38190b15e4d6bdf0c97fb4fca8412226d287 # v5.3.0 + uses: actions/setup-java@03ad4de0992f5dab5e18fcb136590ce7c4a0ac95 # v5.6.0 with: java-version: '21' distribution: 'temurin' diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 058c778..1147df6 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -19,10 +19,10 @@ jobs: steps: - name: Checkout - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0 - name: Set up JDK 21 - uses: actions/setup-java@ad2b38190b15e4d6bdf0c97fb4fca8412226d287 # v5.3.0 + uses: actions/setup-java@03ad4de0992f5dab5e18fcb136590ce7c4a0ac95 # v5.6.0 with: java-version: '21' distribution: 'temurin' diff --git a/README.md b/README.md index 8134ae8..d417bd1 100644 --- a/README.md +++ b/README.md @@ -38,20 +38,20 @@ To install the library, add the following lines to your build config file. io.qdrant client - 1.18.3 + 1.19.0 ``` #### SBT ```sbt -libraryDependencies += "io.qdrant" % "client" % "1.18.3" +libraryDependencies += "io.qdrant" % "client" % "1.19.0" ``` #### Gradle ```gradle -implementation 'io.qdrant:client:1.18.3' +implementation 'io.qdrant:client:1.19.0' ``` > [!NOTE] diff --git a/build.gradle b/build.gradle index 0c19981..575ced0 100644 --- a/build.gradle +++ b/build.gradle @@ -21,7 +21,7 @@ plugins { id 'com.google.protobuf' version '0.10.0' id 'net.ltgt.errorprone' version '5.1.0' id 'io.github.gradle-nexus.publish-plugin' version '2.0.0' - id 'com.diffplug.spotless' version '8.7.0' + id 'com.diffplug.spotless' version '8.8.0' } group = 'io.qdrant' @@ -79,14 +79,14 @@ jar { } } -def grpcVersion = '1.82.0' +def grpcVersion = '1.83.0' def protocVersion = '3.25.5' def slf4jVersion = '2.0.18' def testcontainersVersion = '1.21.4' -def jUnitVersion = '6.1.0' +def jUnitVersion = '6.1.2' dependencies { - errorprone "com.uber.nullaway:nullaway:0.13.7" + errorprone "com.uber.nullaway:nullaway:0.13.8" api "io.grpc:grpc-protobuf:${grpcVersion}" api "io.grpc:grpc-stub:${grpcVersion}" diff --git a/example/build.gradle b/example/build.gradle index 1952c13..c9780ab 100644 --- a/example/build.gradle +++ b/example/build.gradle @@ -13,7 +13,7 @@ repositories { dependencies { // Qdrant Java client - implementation 'io.qdrant:client:1.18.3' + implementation 'io.qdrant:client:1.19.0' // gRPC dependencies - use the same version as Qdrant client implementation 'io.grpc:grpc-netty-shaded:1.65.1' diff --git a/gradle.properties b/gradle.properties index dc0b8fe..2a1d835 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,8 +1,8 @@ # The version of qdrant to use to download protos -qdrantProtosVersion=v1.18.0 +qdrantProtosVersion=v1.19.0 # The version of qdrant docker image to run integration tests against -qdrantVersion=v1.18.0 +qdrantVersion=v1.19.0 # The version of the client to generate -packageVersion=1.18.3 +packageVersion=1.19.0 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index eb84db6..a9db115 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-9.6.0-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.6.1-bin.zip networkTimeout=10000 retries=0 retryBackOffMs=500 diff --git a/src/main/java/io/qdrant/client/ConditionFactory.java b/src/main/java/io/qdrant/client/ConditionFactory.java index d9a04bf..40c6a36 100644 --- a/src/main/java/io/qdrant/client/ConditionFactory.java +++ b/src/main/java/io/qdrant/client/ConditionFactory.java @@ -19,6 +19,7 @@ import io.qdrant.client.grpc.Common.Range; import io.qdrant.client.grpc.Common.RepeatedIntegers; import io.qdrant.client.grpc.Common.RepeatedStrings; +import io.qdrant.client.grpc.Common.SliceCondition; import io.qdrant.client.grpc.Common.ValuesCount; import java.util.List; @@ -142,6 +143,25 @@ public static Condition matchTextAny(String field, String textAny) { .build(); } + /** + * Match records where the given field starts with the given keyword prefix. + * + *

The field must have a keyword index with prefix matching enabled. + * + * @param field The name of the field + * @param prefix The keyword prefix to match + * @return a new instance of {@link Condition} + */ + public static Condition matchPrefix(String field, String prefix) { + return Condition.newBuilder() + .setField( + FieldCondition.newBuilder() + .setKey(field) + .setMatch(Match.newBuilder().setPrefix(prefix).build()) + .build()) + .build(); + } + /** * Match records where the given field matches the given boolean value. * @@ -427,6 +447,19 @@ public static Condition datetimeRange(String field, DatetimeRange datetimeRange) .build(); } + /** + * Selects one deterministic slice of the point ID space. + * + * @param total The total number of disjoint slices. Must be at least 1 + * @param index The slice to select. Must be less than {@code total} + * @return a new instance of {@link Condition} + */ + public static Condition slice(int total, int index) { + return Condition.newBuilder() + .setSlice(SliceCondition.newBuilder().setTotal(total).setIndex(index).build()) + .build(); + } + /** * Matches records where a value for the given vector is present. * diff --git a/src/main/java/io/qdrant/client/StemmingAlgorithmFactory.java b/src/main/java/io/qdrant/client/StemmingAlgorithmFactory.java new file mode 100644 index 0000000..3964e42 --- /dev/null +++ b/src/main/java/io/qdrant/client/StemmingAlgorithmFactory.java @@ -0,0 +1,31 @@ +package io.qdrant.client; + +import io.qdrant.client.grpc.Collections.DisabledStemmer; +import io.qdrant.client.grpc.Collections.SnowballParams; +import io.qdrant.client.grpc.Collections.StemmingAlgorithm; + +/** Convenience methods for constructing {@link StemmingAlgorithm}. */ +public final class StemmingAlgorithmFactory { + private StemmingAlgorithmFactory() {} + + /** + * Creates a Snowball stemming algorithm for the given language. + * + * @param language The language whose words should be stemmed + * @return a new instance of {@link StemmingAlgorithm} + */ + public static StemmingAlgorithm snowball(String language) { + return StemmingAlgorithm.newBuilder() + .setSnowball(SnowballParams.newBuilder().setLanguage(language).build()) + .build(); + } + + /** + * Explicitly disables stemming, overriding the language default. + * + * @return a new instance of {@link StemmingAlgorithm} + */ + public static StemmingAlgorithm disabled() { + return StemmingAlgorithm.newBuilder().setDisabled(DisabledStemmer.getDefaultInstance()).build(); + } +}