diff --git a/qdrant-landing/content/documentation/guides/distributed_deployment.md b/qdrant-landing/content/documentation/guides/distributed_deployment.md
index 8d08d28ee..07f962f6a 100644
--- a/qdrant-landing/content/documentation/guides/distributed_deployment.md
+++ b/qdrant-landing/content/documentation/guides/distributed_deployment.md
@@ -195,6 +195,34 @@ client
.await?;
```
+```java
+import io.qdrant.client.QdrantClient;
+import io.qdrant.client.QdrantGrpcClient;
+import io.qdrant.client.grpc.Collections.CreateCollection;
+import io.qdrant.client.grpc.Collections.Distance;
+import io.qdrant.client.grpc.Collections.VectorParams;
+import io.qdrant.client.grpc.Collections.VectorsConfig;
+
+QdrantClient client =
+ new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
+
+client
+ .createCollectionAsync(
+ CreateCollection.newBuilder()
+ .setCollectionName("{collection_name}")
+ .setVectorsConfig(
+ VectorsConfig.newBuilder()
+ .setParams(
+ VectorParams.newBuilder()
+ .setSize(300)
+ .setDistance(Distance.Cosine)
+ .build())
+ .build())
+ .setShardNumber(6)
+ .build())
+ .get();
+```
+
We recommend setting the number of shards to be a multiple of the number of nodes you are currently running in your cluster.
For example, if you have 3 nodes, 6 shards could be a good option.
@@ -301,6 +329,26 @@ client
.await?;
```
+```java
+import io.qdrant.client.QdrantClient;
+import io.qdrant.client.QdrantGrpcClient;
+import io.qdrant.client.grpc.Collections.CreateCollection;
+import io.qdrant.client.grpc.Collections.ShardingMethod;
+
+QdrantClient client =
+ new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
+
+client
+ .createCollectionAsync(
+ CreateCollection.newBuilder()
+ .setCollectionName("{collection_name}")
+ // ... other collection parameters
+ .setShardNumber(1)
+ .setShardingMethod(ShardingMethod.Custom)
+ .build())
+ .get();
+```
+
In this mode, the `shard_number` means the number of shards per shard key, where points will be distributed evenly. For example, if you have 10 shard keys and a collection config with these settings:
```json
@@ -379,6 +427,36 @@ client
.await?;
```
+```java
+import java.util.List;
+
+import static io.qdrant.client.PointIdFactory.id;
+import static io.qdrant.client.ShardKeySelectorFactory.shardKeySelector;
+import static io.qdrant.client.VectorsFactory.vectors;
+
+import io.qdrant.client.QdrantClient;
+import io.qdrant.client.QdrantGrpcClient;
+import io.qdrant.client.grpc.Points.PointStruct;
+import io.qdrant.client.grpc.Points.UpsertPoints;
+
+QdrantClient client =
+ new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
+
+client
+ .upsertAsync(
+ UpsertPoints.newBuilder()
+ .setCollectionName("{collection_name}")
+ .addAllPoints(
+ List.of(
+ PointStruct.newBuilder()
+ .setId(id(111))
+ .setVectors(vectors(0.1f, 0.2f, 0.3f))
+ .build()))
+ .setShardKeySelector(shardKeySelector("user_1"))
+ .build())
+ .get();
+```
+
@@ -553,6 +631,35 @@ client
.await?;
```
+```java
+import io.qdrant.client.QdrantClient;
+import io.qdrant.client.QdrantGrpcClient;
+import io.qdrant.client.grpc.Collections.CreateCollection;
+import io.qdrant.client.grpc.Collections.Distance;
+import io.qdrant.client.grpc.Collections.VectorParams;
+import io.qdrant.client.grpc.Collections.VectorsConfig;
+
+QdrantClient client =
+ new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
+
+client
+ .createCollectionAsync(
+ CreateCollection.newBuilder()
+ .setCollectionName("{collection_name}")
+ .setVectorsConfig(
+ VectorsConfig.newBuilder()
+ .setParams(
+ VectorParams.newBuilder()
+ .setSize(300)
+ .setDistance(Distance.Cosine)
+ .build())
+ .build())
+ .setShardNumber(6)
+ .setReplicationFactor(2)
+ .build())
+ .get();
+```
+
This code sample creates a collection with a total of 6 logical shards backed by a total of 12 physical shards.
Since a replication factor of "2" would require twice as much storage space, it is advised to make sure the hardware can host the additional shard replicas beforehand.
@@ -752,6 +859,36 @@ client
.await?;
```
+```java
+import io.qdrant.client.QdrantClient;
+import io.qdrant.client.QdrantGrpcClient;
+import io.qdrant.client.grpc.Collections.CreateCollection;
+import io.qdrant.client.grpc.Collections.Distance;
+import io.qdrant.client.grpc.Collections.VectorParams;
+import io.qdrant.client.grpc.Collections.VectorsConfig;
+
+QdrantClient client =
+ new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
+
+client
+ .createCollectionAsync(
+ CreateCollection.newBuilder()
+ .setCollectionName("{collection_name}")
+ .setVectorsConfig(
+ VectorsConfig.newBuilder()
+ .setParams(
+ VectorParams.newBuilder()
+ .setSize(300)
+ .setDistance(Distance.Cosine)
+ .build())
+ .build())
+ .setShardNumber(6)
+ .setReplicationFactor(2)
+ .setWriteConsistencyFactor(2)
+ .build())
+ .get();
+```
+
Write operations will fail if the number of active replicas is less than the `write_consistency_factor`.
### Read consistency
@@ -855,6 +992,36 @@ client
.await?;
```
+```java
+import java.util.List;
+
+import static io.qdrant.client.ConditionFactory.matchKeyword;
+
+import io.qdrant.client.QdrantClient;
+import io.qdrant.client.QdrantGrpcClient;
+import io.qdrant.client.grpc.Points.Filter;
+import io.qdrant.client.grpc.Points.ReadConsistency;
+import io.qdrant.client.grpc.Points.ReadConsistencyType;
+import io.qdrant.client.grpc.Points.SearchParams;
+import io.qdrant.client.grpc.Points.SearchPoints;
+
+QdrantClient client =
+ new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
+
+client
+ .searchAsync(
+ SearchPoints.newBuilder()
+ .setCollectionName("{collection_name}")
+ .setFilter(Filter.newBuilder().addMust(matchKeyword("city", "London")).build())
+ .setParams(SearchParams.newBuilder().setHnswEf(128).setExact(true).build())
+ .addAllVector(List.of(0.2f, 0.1f, 0.9f, 0.7f))
+ .setLimit(3)
+ .setReadConsistency(
+ ReadConsistency.newBuilder().setType(ReadConsistencyType.Majority).build())
+ .build())
+ .get();
+```
+
### Write ordering
Write `ordering` can be specified for any write request to serialize it through a single "leader" node,
@@ -963,6 +1130,45 @@ client
.await?;
```
+```java
+import java.util.List;
+import java.util.Map;
+
+import static io.qdrant.client.PointIdFactory.id;
+import static io.qdrant.client.ValueFactory.value;
+import static io.qdrant.client.VectorsFactory.vectors;
+
+import io.qdrant.client.grpc.Points.PointStruct;
+import io.qdrant.client.grpc.Points.UpsertPoints;
+import io.qdrant.client.grpc.Points.WriteOrdering;
+import io.qdrant.client.grpc.Points.WriteOrderingType;
+
+client
+ .upsertAsync(
+ UpsertPoints.newBuilder()
+ .setCollectionName("{collection_name}")
+ .addAllPoints(
+ List.of(
+ PointStruct.newBuilder()
+ .setId(id(1))
+ .setVectors(vectors(0.9f, 0.1f, 0.1f))
+ .putAllPayload(Map.of("color", value("red")))
+ .build(),
+ PointStruct.newBuilder()
+ .setId(id(2))
+ .setVectors(vectors(0.1f, 0.9f, 0.1f))
+ .putAllPayload(Map.of("color", value("green")))
+ .build(),
+ PointStruct.newBuilder()
+ .setId(id(3))
+ .setVectors(vectors(0.1f, 0.1f, 0.94f))
+ .putAllPayload(Map.of("color", value("blue")))
+ .build()))
+ .setOrdering(WriteOrdering.newBuilder().setType(WriteOrderingType.Strong).build())
+ .build())
+ .get();
+```
+
## Listener mode
diff --git a/qdrant-landing/content/documentation/guides/multiple-partitions.md b/qdrant-landing/content/documentation/guides/multiple-partitions.md
index 5c290b221..bf414d6ee 100644
--- a/qdrant-landing/content/documentation/guides/multiple-partitions.md
+++ b/qdrant-landing/content/documentation/guides/multiple-partitions.md
@@ -132,6 +132,39 @@ client
.await?;
```
+```java
+import java.util.List;
+import java.util.Map;
+
+import io.qdrant.client.QdrantClient;
+import io.qdrant.client.QdrantGrpcClient;
+import io.qdrant.client.grpc.Points.PointStruct;
+
+QdrantClient client =
+ new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
+
+client
+ .upsertAsync(
+ "{collection_name}",
+ List.of(
+ PointStruct.newBuilder()
+ .setId(id(1))
+ .setVectors(vectors(0.9f, 0.1f, 0.1f))
+ .putAllPayload(Map.of("group_id", value("user_1")))
+ .build(),
+ PointStruct.newBuilder()
+ .setId(id(2))
+ .setVectors(vectors(0.1f, 0.9f, 0.1f))
+ .putAllPayload(Map.of("group_id", value("user_1")))
+ .build(),
+ PointStruct.newBuilder()
+ .setId(id(3))
+ .setVectors(vectors(0.1f, 0.1f, 0.9f))
+ .putAllPayload(Map.of("group_id", value("user_2")))
+ .build()))
+ .get();
+```
+
2. Use a filter along with `group_id` to filter vectors for each user.
```http
@@ -210,6 +243,29 @@ client
.await?;
```
+```java
+import java.util.List;
+
+import io.qdrant.client.QdrantClient;
+import io.qdrant.client.QdrantGrpcClient;
+import io.qdrant.client.grpc.Points.Filter;
+import io.qdrant.client.grpc.Points.SearchPoints;
+
+QdrantClient client =
+ new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
+
+client
+ .searchAsync(
+ SearchPoints.newBuilder()
+ .setCollectionName("{collection_name}")
+ .setFilter(
+ Filter.newBuilder().addMust(matchKeyword("group_id", "user_1")).build())
+ .addAllVector(List.of(0.1f, 0.1f, 0.9f))
+ .setLimit(10)
+ .build())
+ .get();
+```
+
## Calibrate performance
The speed of indexation may become a bottleneck in this case, as each user's vector will be indexed into the same collection. To avoid this bottleneck, consider _bypassing the construction of a global vector index_ for the entire collection and building it only for individual groups instead.
@@ -298,6 +354,35 @@ client
.await?;
```
+```java
+import io.qdrant.client.QdrantClient;
+import io.qdrant.client.QdrantGrpcClient;
+import io.qdrant.client.grpc.Collections.CreateCollection;
+import io.qdrant.client.grpc.Collections.Distance;
+import io.qdrant.client.grpc.Collections.HnswConfigDiff;
+import io.qdrant.client.grpc.Collections.VectorParams;
+import io.qdrant.client.grpc.Collections.VectorsConfig;
+
+QdrantClient client =
+ new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
+
+client
+ .createCollectionAsync(
+ CreateCollection.newBuilder()
+ .setCollectionName("{collection_name}")
+ .setVectorsConfig(
+ VectorsConfig.newBuilder()
+ .setParams(
+ VectorParams.newBuilder()
+ .setSize(768)
+ .setDistance(Distance.Cosine)
+ .build())
+ .build())
+ .setHnswConfig(HnswConfigDiff.newBuilder().setPayloadM(16).setM(0).build())
+ .build())
+ .get();
+```
+
3. Create keyword payload index for `group_id` field.
```http
@@ -339,6 +424,20 @@ client
.await?;
```
+```java
+import io.qdrant.client.QdrantClient;
+import io.qdrant.client.QdrantGrpcClient;
+import io.qdrant.client.grpc.Collections.PayloadSchemaType;
+
+QdrantClient client =
+ new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
+
+client
+ .createPayloadIndexAsync(
+ "{collection_name}", "group_id", PayloadSchemaType.Keyword, null, null, null, null)
+ .get();
+```
+
## Limitations
One downside to this approach is that global requests (without the `group_id` filter) will be slower since they will necessitate scanning all groups to identify the nearest neighbors.
diff --git a/qdrant-landing/content/documentation/guides/optimize.md b/qdrant-landing/content/documentation/guides/optimize.md
index 3b8a44808..a8896edbb 100644
--- a/qdrant-landing/content/documentation/guides/optimize.md
+++ b/qdrant-landing/content/documentation/guides/optimize.md
@@ -120,6 +120,47 @@ client
.await?;
```
+```java
+import io.qdrant.client.QdrantClient;
+import io.qdrant.client.QdrantGrpcClient;
+import io.qdrant.client.grpc.Collections.CreateCollection;
+import io.qdrant.client.grpc.Collections.Distance;
+import io.qdrant.client.grpc.Collections.OptimizersConfigDiff;
+import io.qdrant.client.grpc.Collections.QuantizationConfig;
+import io.qdrant.client.grpc.Collections.QuantizationType;
+import io.qdrant.client.grpc.Collections.ScalarQuantization;
+import io.qdrant.client.grpc.Collections.VectorParams;
+import io.qdrant.client.grpc.Collections.VectorsConfig;
+
+QdrantClient client =
+ new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
+
+client
+ .createCollectionAsync(
+ CreateCollection.newBuilder()
+ .setCollectionName("{collection_name}")
+ .setVectorsConfig(
+ VectorsConfig.newBuilder()
+ .setParams(
+ VectorParams.newBuilder()
+ .setSize(768)
+ .setDistance(Distance.Cosine)
+ .build())
+ .build())
+ .setOptimizersConfig(
+ OptimizersConfigDiff.newBuilder().setMemmapThreshold(20000).build())
+ .setQuantizationConfig(
+ QuantizationConfig.newBuilder()
+ .setScalar(
+ ScalarQuantization.newBuilder()
+ .setType(QuantizationType.Int8)
+ .setAlwaysRam(true)
+ .build())
+ .build())
+ .build())
+ .get();
+```
+
`mmmap_threshold` will ensure that vectors will be stored on disk, while `always_ram` will ensure that quantized vectors will be stored in RAM.
Optionally, you can disable rescoring with search `params`, which will reduce the number of disk reads even further, but potentially slightly decrease the precision.
@@ -192,6 +233,32 @@ client
.await?;
```
+```java
+import java.util.List;
+
+import io.qdrant.client.QdrantClient;
+import io.qdrant.client.QdrantGrpcClient;
+import io.qdrant.client.grpc.Points.QuantizationSearchParams;
+import io.qdrant.client.grpc.Points.SearchParams;
+import io.qdrant.client.grpc.Points.SearchPoints;
+QdrantClient client =
+ new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
+
+client
+ .searchAsync(
+ SearchPoints.newBuilder()
+ .setCollectionName("{collection_name}")
+ .addAllVector(List.of(0.2f, 0.1f, 0.9f, 0.7f))
+ .setParams(
+ SearchParams.newBuilder()
+ .setQuantization(
+ QuantizationSearchParams.newBuilder().setRescore(false).build())
+ .build())
+ .setLimit(3)
+ .build())
+ .get();
+```
+
## Prefer high precision with low memory footprint
In case you need high precision, but don't have enough RAM to store vectors in memory, you can enable on-disk vectors and HNSW index.
@@ -278,6 +345,38 @@ client
.await?;
```
+```java
+import io.qdrant.client.QdrantClient;
+import io.qdrant.client.QdrantGrpcClient;
+import io.qdrant.client.grpc.Collections.CreateCollection;
+import io.qdrant.client.grpc.Collections.Distance;
+import io.qdrant.client.grpc.Collections.HnswConfigDiff;
+import io.qdrant.client.grpc.Collections.OptimizersConfigDiff;
+import io.qdrant.client.grpc.Collections.VectorParams;
+import io.qdrant.client.grpc.Collections.VectorsConfig;
+
+QdrantClient client =
+ new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
+
+client
+ .createCollectionAsync(
+ CreateCollection.newBuilder()
+ .setCollectionName("{collection_name}")
+ .setVectorsConfig(
+ VectorsConfig.newBuilder()
+ .setParams(
+ VectorParams.newBuilder()
+ .setSize(768)
+ .setDistance(Distance.Cosine)
+ .build())
+ .build())
+ .setOptimizersConfig(
+ OptimizersConfigDiff.newBuilder().setMemmapThreshold(20000).build())
+ .setHnswConfig(HnswConfigDiff.newBuilder().setOnDisk(true).build())
+ .build())
+ .get();
+```
+
In this scenario you can increase the precision of the search by increasing the `ef` and `m` parameters of the HNSW index, even with limited RAM.
```json
@@ -398,6 +497,47 @@ client
.await?;
```
+```java
+import io.qdrant.client.QdrantClient;
+import io.qdrant.client.QdrantGrpcClient;
+import io.qdrant.client.grpc.Collections.CreateCollection;
+import io.qdrant.client.grpc.Collections.Distance;
+import io.qdrant.client.grpc.Collections.OptimizersConfigDiff;
+import io.qdrant.client.grpc.Collections.QuantizationConfig;
+import io.qdrant.client.grpc.Collections.QuantizationType;
+import io.qdrant.client.grpc.Collections.ScalarQuantization;
+import io.qdrant.client.grpc.Collections.VectorParams;
+import io.qdrant.client.grpc.Collections.VectorsConfig;
+
+QdrantClient client =
+ new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
+
+client
+ .createCollectionAsync(
+ CreateCollection.newBuilder()
+ .setCollectionName("{collection_name}")
+ .setVectorsConfig(
+ VectorsConfig.newBuilder()
+ .setParams(
+ VectorParams.newBuilder()
+ .setSize(768)
+ .setDistance(Distance.Cosine)
+ .build())
+ .build())
+ .setOptimizersConfig(
+ OptimizersConfigDiff.newBuilder().setMemmapThreshold(20000).build())
+ .setQuantizationConfig(
+ QuantizationConfig.newBuilder()
+ .setScalar(
+ ScalarQuantization.newBuilder()
+ .setType(QuantizationType.Int8)
+ .setAlwaysRam(true)
+ .build())
+ .build())
+ .build())
+ .get();
+```
+
There are also some search-time parameters you can use to tune the search accuracy and speed:
```http
@@ -463,6 +603,28 @@ client
.await?;
```
+```java
+import java.util.List;
+
+import io.qdrant.client.QdrantClient;
+import io.qdrant.client.QdrantGrpcClient;
+import io.qdrant.client.grpc.Points.SearchParams;
+import io.qdrant.client.grpc.Points.SearchPoints;
+
+QdrantClient client =
+ new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
+
+client
+ .searchAsync(
+ SearchPoints.newBuilder()
+ .setCollectionName("{collection_name}")
+ .addAllVector(List.of(0.2f, 0.1f, 0.9f, 0.7f))
+ .setParams(SearchParams.newBuilder().setHnswEf(128).setExact(false).build())
+ .setLimit(3)
+ .build())
+ .get();
+```
+
- `hnsw_ef` - controls the number of neighbors to visit during search. The higher the value, the more accurate and slower the search will be. Recommended range is 32-512.
- `exact` - if set to `true`, will perform exact search, which will be slower, but more accurate. You can use it to compare results of the search with different `hnsw_ef` values versus the ground truth.
@@ -548,6 +710,36 @@ client
.await?;
```
+```java
+import io.qdrant.client.QdrantClient;
+import io.qdrant.client.QdrantGrpcClient;
+import io.qdrant.client.grpc.Collections.CreateCollection;
+import io.qdrant.client.grpc.Collections.Distance;
+import io.qdrant.client.grpc.Collections.OptimizersConfigDiff;
+import io.qdrant.client.grpc.Collections.VectorParams;
+import io.qdrant.client.grpc.Collections.VectorsConfig;
+
+QdrantClient client =
+ new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
+
+client
+ .createCollectionAsync(
+ CreateCollection.newBuilder()
+ .setCollectionName("{collection_name}")
+ .setVectorsConfig(
+ VectorsConfig.newBuilder()
+ .setParams(
+ VectorParams.newBuilder()
+ .setSize(768)
+ .setDistance(Distance.Cosine)
+ .build())
+ .build())
+ .setOptimizersConfig(
+ OptimizersConfigDiff.newBuilder().setDefaultSegmentNumber(16).build())
+ .build())
+ .get();
+```
+
To prefer throughput, you can set up Qdrant to use as many cores as possible for processing multiple requests in parallel.
To do that, you can configure qdrant to use minimal number of segments, which is usually 2.
Large segments benefit from the size of the index and overall smaller number of vector comparisons required to find the nearest neighbors. But at the same time require more time to build index.
@@ -622,3 +814,34 @@ client
})
.await?;
```
+
+```java
+import io.qdrant.client.QdrantClient;
+import io.qdrant.client.QdrantGrpcClient;
+import io.qdrant.client.grpc.Collections.CreateCollection;
+import io.qdrant.client.grpc.Collections.Distance;
+import io.qdrant.client.grpc.Collections.OptimizersConfigDiff;
+import io.qdrant.client.grpc.Collections.VectorParams;
+import io.qdrant.client.grpc.Collections.VectorsConfig;
+
+QdrantClient client =
+ new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
+
+client
+ .createCollectionAsync(
+ CreateCollection.newBuilder()
+ .setCollectionName("{collection_name}")
+ .setVectorsConfig(
+ VectorsConfig.newBuilder()
+ .setParams(
+ VectorParams.newBuilder()
+ .setSize(768)
+ .setDistance(Distance.Cosine)
+ .build())
+ .build())
+ .setOptimizersConfig(
+ OptimizersConfigDiff.newBuilder().setDefaultSegmentNumber(2).build())
+ .build())
+ .get();
+```
+
diff --git a/qdrant-landing/content/documentation/guides/quantization.md b/qdrant-landing/content/documentation/guides/quantization.md
index 3f330b8b1..67d056ee1 100644
--- a/qdrant-landing/content/documentation/guides/quantization.md
+++ b/qdrant-landing/content/documentation/guides/quantization.md
@@ -236,6 +236,45 @@ client
.await?;
```
+```java
+import io.qdrant.client.QdrantClient;
+import io.qdrant.client.QdrantGrpcClient;
+import io.qdrant.client.grpc.Collections.CreateCollection;
+import io.qdrant.client.grpc.Collections.Distance;
+import io.qdrant.client.grpc.Collections.QuantizationConfig;
+import io.qdrant.client.grpc.Collections.QuantizationType;
+import io.qdrant.client.grpc.Collections.ScalarQuantization;
+import io.qdrant.client.grpc.Collections.VectorParams;
+import io.qdrant.client.grpc.Collections.VectorsConfig;
+
+QdrantClient client =
+ new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
+
+client
+ .createCollectionAsync(
+ CreateCollection.newBuilder()
+ .setCollectionName("{collection_name}")
+ .setVectorsConfig(
+ VectorsConfig.newBuilder()
+ .setParams(
+ VectorParams.newBuilder()
+ .setSize(768)
+ .setDistance(Distance.Cosine)
+ .build())
+ .build())
+ .setQuantizationConfig(
+ QuantizationConfig.newBuilder()
+ .setScalar(
+ ScalarQuantization.newBuilder()
+ .setType(QuantizationType.Int8)
+ .setQuantile(0.99f)
+ .setAlwaysRam(true)
+ .build())
+ .build())
+ .build())
+ .get();
+```
+
There are 3 parameters that you can specify in the `quantization_config` section:
`type` - the type of the quantized vector components. Currently, Qdrant supports only `int8`.
@@ -338,6 +377,39 @@ client
.await?;
```
+```java
+import io.qdrant.client.QdrantClient;
+import io.qdrant.client.QdrantGrpcClient;
+import io.qdrant.client.grpc.Collections.BinaryQuantization;
+import io.qdrant.client.grpc.Collections.CreateCollection;
+import io.qdrant.client.grpc.Collections.Distance;
+import io.qdrant.client.grpc.Collections.QuantizationConfig;
+import io.qdrant.client.grpc.Collections.VectorParams;
+import io.qdrant.client.grpc.Collections.VectorsConfig;
+
+QdrantClient client =
+ new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
+
+client
+ .createCollectionAsync(
+ CreateCollection.newBuilder()
+ .setCollectionName("{collection_name}")
+ .setVectorsConfig(
+ VectorsConfig.newBuilder()
+ .setParams(
+ VectorParams.newBuilder()
+ .setSize(1536)
+ .setDistance(Distance.Cosine)
+ .build())
+ .build())
+ .setQuantizationConfig(
+ QuantizationConfig.newBuilder()
+ .setBinary(BinaryQuantization.newBuilder().setAlwaysRam(true).build())
+ .build())
+ .build())
+ .get();
+```
+
`always_ram` - whether to keep quantized vectors always cached in RAM or not. By default, quantized vectors are loaded in the same way as the original vectors.
However, in some setups you might want to keep quantized vectors in RAM to speed up the search process.
@@ -433,6 +505,44 @@ client
.await?;
```
+```java
+import io.qdrant.client.QdrantClient;
+import io.qdrant.client.QdrantGrpcClient;
+import io.qdrant.client.grpc.Collections.CompressionRatio;
+import io.qdrant.client.grpc.Collections.CreateCollection;
+import io.qdrant.client.grpc.Collections.Distance;
+import io.qdrant.client.grpc.Collections.ProductQuantization;
+import io.qdrant.client.grpc.Collections.QuantizationConfig;
+import io.qdrant.client.grpc.Collections.VectorParams;
+import io.qdrant.client.grpc.Collections.VectorsConfig;
+
+QdrantClient client =
+ new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
+
+client
+ .createCollectionAsync(
+ CreateCollection.newBuilder()
+ .setCollectionName("{collection_name}")
+ .setVectorsConfig(
+ VectorsConfig.newBuilder()
+ .setParams(
+ VectorParams.newBuilder()
+ .setSize(768)
+ .setDistance(Distance.Cosine)
+ .build())
+ .build())
+ .setQuantizationConfig(
+ QuantizationConfig.newBuilder()
+ .setProduct(
+ ProductQuantization.newBuilder()
+ .setCompression(CompressionRatio.x16)
+ .setAlwaysRam(true)
+ .build())
+ .build())
+ .build())
+ .get();
+```
+
There are two parameters that you can specify in the `quantization_config` section:
`compression` - compression ratio.
@@ -528,6 +638,37 @@ client
.await?;
```
+```java
+import java.util.List;
+
+import io.qdrant.client.QdrantClient;
+import io.qdrant.client.QdrantGrpcClient;
+import io.qdrant.client.grpc.Points.QuantizationSearchParams;
+import io.qdrant.client.grpc.Points.SearchParams;
+import io.qdrant.client.grpc.Points.SearchPoints;
+
+QdrantClient client =
+ new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
+
+client
+ .searchAsync(
+ SearchPoints.newBuilder()
+ .setCollectionName("{collection_name}")
+ .addAllVector(List.of(0.2f, 0.1f, 0.9f, 0.7f))
+ .setParams(
+ SearchParams.newBuilder()
+ .setQuantization(
+ QuantizationSearchParams.newBuilder()
+ .setIgnore(false)
+ .setRescore(true)
+ .setOversampling(2.0)
+ .build())
+ .build())
+ .setLimit(10)
+ .build())
+ .get();
+```
+
`ignore` - Toggle whether to ignore quantized vectors during the search process. By default, Qdrant will use quantized vectors if they are available.
`rescore` - Having the original vectors available, Qdrant can re-evaluate top-k search results using the original vectors.
@@ -619,6 +760,33 @@ client
.await?;
```
+```java
+import java.util.List;
+
+import io.qdrant.client.QdrantClient;
+import io.qdrant.client.QdrantGrpcClient;
+import io.qdrant.client.grpc.Points.QuantizationSearchParams;
+import io.qdrant.client.grpc.Points.SearchParams;
+import io.qdrant.client.grpc.Points.SearchPoints;
+
+QdrantClient client =
+ new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
+
+client
+ .searchAsync(
+ SearchPoints.newBuilder()
+ .setCollectionName("{collection_name}")
+ .addAllVector(List.of(0.2f, 0.1f, 0.9f, 0.7f))
+ .setParams(
+ SearchParams.newBuilder()
+ .setQuantization(
+ QuantizationSearchParams.newBuilder().setIgnore(true).build())
+ .build())
+ .setLimit(10)
+ .build())
+ .get();
+```
+
- **Adjust the quantile parameter**: The quantile parameter in scalar quantization determines the quantization bounds.
By setting it to a value lower than 1.0, you can exclude extreme values (outliers) from the quantization bounds.
For example, if you set the quantile to 0.99, 1% of the extreme values will be excluded.
@@ -736,6 +904,47 @@ client
.await?;
```
+```java
+import io.qdrant.client.QdrantClient;
+import io.qdrant.client.QdrantGrpcClient;
+import io.qdrant.client.grpc.Collections.CreateCollection;
+import io.qdrant.client.grpc.Collections.Distance;
+import io.qdrant.client.grpc.Collections.OptimizersConfigDiff;
+import io.qdrant.client.grpc.Collections.QuantizationConfig;
+import io.qdrant.client.grpc.Collections.QuantizationType;
+import io.qdrant.client.grpc.Collections.ScalarQuantization;
+import io.qdrant.client.grpc.Collections.VectorParams;
+import io.qdrant.client.grpc.Collections.VectorsConfig;
+
+QdrantClient client =
+ new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
+
+client
+ .createCollectionAsync(
+ CreateCollection.newBuilder()
+ .setCollectionName("{collection_name}")
+ .setVectorsConfig(
+ VectorsConfig.newBuilder()
+ .setParams(
+ VectorParams.newBuilder()
+ .setSize(768)
+ .setDistance(Distance.Cosine)
+ .build())
+ .build())
+ .setOptimizersConfig(
+ OptimizersConfigDiff.newBuilder().setMemmapThreshold(20000).build())
+ .setQuantizationConfig(
+ QuantizationConfig.newBuilder()
+ .setScalar(
+ ScalarQuantization.newBuilder()
+ .setType(QuantizationType.Int8)
+ .setAlwaysRam(true)
+ .build())
+ .build())
+ .build())
+ .get();
+```
+
In this scenario, the number of disk reads may play a significant role in the search speed.
In a system with high disk latency, the re-scoring step may become a bottleneck.
@@ -808,6 +1017,33 @@ client
.await?;
```
+```java
+import java.util.List;
+
+import io.qdrant.client.QdrantClient;
+import io.qdrant.client.QdrantGrpcClient;
+import io.qdrant.client.grpc.Points.QuantizationSearchParams;
+import io.qdrant.client.grpc.Points.SearchParams;
+import io.qdrant.client.grpc.Points.SearchPoints;
+
+QdrantClient client =
+ new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
+
+client
+ .searchAsync(
+ SearchPoints.newBuilder()
+ .setCollectionName("{collection_name}")
+ .addAllVector(List.of(0.2f, 0.1f, 0.9f, 0.7f))
+ .setParams(
+ SearchParams.newBuilder()
+ .setQuantization(
+ QuantizationSearchParams.newBuilder().setRescore(false).build())
+ .build())
+ .setLimit(3)
+ .build())
+ .get();
+```
+
- **All on Disk** - all vectors, original and quantized, are stored on disk. This mode allows to achieve the smallest memory footprint, but at the cost of the search speed.
It is recommended to use this mode if you have a large collection and fast storage (e.g. SSD or NVMe).
@@ -910,3 +1146,44 @@ client
})
.await?;
```
+
+```java
+import io.qdrant.client.QdrantClient;
+import io.qdrant.client.QdrantGrpcClient;
+import io.qdrant.client.grpc.Collections.CreateCollection;
+import io.qdrant.client.grpc.Collections.Distance;
+import io.qdrant.client.grpc.Collections.OptimizersConfigDiff;
+import io.qdrant.client.grpc.Collections.QuantizationConfig;
+import io.qdrant.client.grpc.Collections.QuantizationType;
+import io.qdrant.client.grpc.Collections.ScalarQuantization;
+import io.qdrant.client.grpc.Collections.VectorParams;
+import io.qdrant.client.grpc.Collections.VectorsConfig;
+
+QdrantClient client =
+ new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
+
+client
+ .createCollectionAsync(
+ CreateCollection.newBuilder()
+ .setCollectionName("{collection_name}")
+ .setVectorsConfig(
+ VectorsConfig.newBuilder()
+ .setParams(
+ VectorParams.newBuilder()
+ .setSize(768)
+ .setDistance(Distance.Cosine)
+ .build())
+ .build())
+ .setOptimizersConfig(
+ OptimizersConfigDiff.newBuilder().setMemmapThreshold(20000).build())
+ .setQuantizationConfig(
+ QuantizationConfig.newBuilder()
+ .setScalar(
+ ScalarQuantization.newBuilder()
+ .setType(QuantizationType.Int8)
+ .setAlwaysRam(false)
+ .build())
+ .build())
+ .build())
+ .get();
+```
\ No newline at end of file