mirror of
https://github.com/qdrant/landing_page.git
synced 2026-09-28 23:48:31 +02:00
docs: C# client usage - II (#607)
* docs: C# client usage guides * docs: use named args * Add files via upload * docs: simplify explore.md list expressions * docs: missed named args * docs: csharp.svg
This commit is contained in:
@@ -52,16 +52,6 @@ const client = new QdrantClient({
|
|||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
```csharp
|
|
||||||
using Qdrant.Client;
|
|
||||||
|
|
||||||
var client = new QdrantClient(
|
|
||||||
host: "xyz-example.eu-central.aws.cloud.qdrant.io",
|
|
||||||
https: true,
|
|
||||||
apiKey: "<paste-your-api-key-here>"
|
|
||||||
);
|
|
||||||
```
|
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
use qdrant_client::client::QdrantClient;
|
use qdrant_client::client::QdrantClient;
|
||||||
|
|
||||||
@@ -84,3 +74,13 @@ QdrantClient client =
|
|||||||
.withApiKey("<paste-your-api-key-here>")
|
.withApiKey("<paste-your-api-key-here>")
|
||||||
.build());
|
.build());
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
using Qdrant.Client;
|
||||||
|
|
||||||
|
var client = new QdrantClient(
|
||||||
|
host: "xyz-example.eu-central.aws.cloud.qdrant.io",
|
||||||
|
https: true,
|
||||||
|
apiKey: "<paste-your-api-key-here>"
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|||||||
@@ -59,16 +59,6 @@ const client = new QdrantClient({
|
|||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
```csharp
|
|
||||||
using Qdrant.Client;
|
|
||||||
|
|
||||||
var client = new QdrantClient(
|
|
||||||
host: "xyz-example.eu-central.aws.cloud.qdrant.io",
|
|
||||||
https: true,
|
|
||||||
apiKey: "<paste-your-api-key-here>"
|
|
||||||
);
|
|
||||||
```
|
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
use qdrant_client::client::QdrantClient;
|
use qdrant_client::client::QdrantClient;
|
||||||
|
|
||||||
@@ -91,3 +81,13 @@ QdrantClient client =
|
|||||||
.withApiKey("<paste-your-api-key-here>")
|
.withApiKey("<paste-your-api-key-here>")
|
||||||
.build());
|
.build());
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
using Qdrant.Client;
|
||||||
|
|
||||||
|
var client = new QdrantClient(
|
||||||
|
host: "xyz-example.eu-central.aws.cloud.qdrant.io",
|
||||||
|
https: true,
|
||||||
|
apiKey: "<paste-your-api-key-here>"
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|||||||
@@ -279,8 +279,8 @@ var client = new QdrantClient("localhost", 6334);
|
|||||||
|
|
||||||
await client.RecommendAsync(
|
await client.RecommendAsync(
|
||||||
collectionName: "{collection_name}",
|
collectionName: "{collection_name}",
|
||||||
positive: new List<ulong> { 100, 231 },
|
positive: new ulong[] { 100, 231 },
|
||||||
negative: new List<ulong> { 718 },
|
negative: new ulong[] { 718 },
|
||||||
usingVector: "image",
|
usingVector: "image",
|
||||||
limit: 10
|
limit: 10
|
||||||
);
|
);
|
||||||
@@ -394,8 +394,8 @@ var client = new QdrantClient("localhost", 6334);
|
|||||||
|
|
||||||
await client.RecommendAsync(
|
await client.RecommendAsync(
|
||||||
collectionName: "{collection_name}",
|
collectionName: "{collection_name}",
|
||||||
positive: new List<ulong> { 100, 231 },
|
positive: new ulong[] { 100, 231 },
|
||||||
negative: new List<ulong> { 718 },
|
negative: new ulong[] { 718 },
|
||||||
usingVector: "image",
|
usingVector: "image",
|
||||||
limit: 10,
|
limit: 10,
|
||||||
lookupFrom: new LookupLocation
|
lookupFrom: new LookupLocation
|
||||||
@@ -600,31 +600,25 @@ var filter = MatchKeyword("city", "london");
|
|||||||
|
|
||||||
await client.RecommendBatchAsync(
|
await client.RecommendBatchAsync(
|
||||||
collectionName: "{collection_name}",
|
collectionName: "{collection_name}",
|
||||||
recommendSearches: new List<RecommendPoints>
|
recommendSearches:
|
||||||
{
|
[
|
||||||
new()
|
new()
|
||||||
{
|
{
|
||||||
CollectionName = "{collection_name}",
|
CollectionName = "{collection_name}",
|
||||||
Positive =
|
Positive = { new PointId[] { 100, 231 } },
|
||||||
{
|
Negative = { new PointId[] { 718 } },
|
||||||
new List<PointId> { 100, 231 }
|
|
||||||
},
|
|
||||||
Negative = { new List<PointId> { 718 } },
|
|
||||||
Limit = 3,
|
Limit = 3,
|
||||||
Filter = filter,
|
Filter = filter,
|
||||||
},
|
},
|
||||||
new()
|
new()
|
||||||
{
|
{
|
||||||
CollectionName = "{collection_name}",
|
CollectionName = "{collection_name}",
|
||||||
Positive =
|
Positive = { new PointId[] { 200, 67 } },
|
||||||
{
|
Negative = { new PointId[] { 300 } },
|
||||||
new List<PointId> { 200, 67 }
|
|
||||||
},
|
|
||||||
Negative = { new List<PointId> { 300 } },
|
|
||||||
Limit = 3,
|
Limit = 3,
|
||||||
Filter = filter,
|
Filter = filter,
|
||||||
}
|
}
|
||||||
}
|
]
|
||||||
);
|
);
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -849,8 +843,8 @@ await client.DiscoverAsync(
|
|||||||
{
|
{
|
||||||
Single = new VectorExample { Vector = new float[] { 0.2f, 0.1f, 0.9f, 0.7f }, }
|
Single = new VectorExample { Vector = new float[] { 0.2f, 0.1f, 0.9f, 0.7f }, }
|
||||||
},
|
},
|
||||||
context: new List<ContextExamplePair>
|
context:
|
||||||
{
|
[
|
||||||
new()
|
new()
|
||||||
{
|
{
|
||||||
Positive = new VectorExample { Id = 100 },
|
Positive = new VectorExample { Id = 100 },
|
||||||
@@ -861,7 +855,7 @@ await client.DiscoverAsync(
|
|||||||
Positive = new VectorExample { Id = 200 },
|
Positive = new VectorExample { Id = 200 },
|
||||||
Negative = new VectorExample { Id = 300 }
|
Negative = new VectorExample { Id = 300 }
|
||||||
}
|
}
|
||||||
},
|
],
|
||||||
limit: 10
|
limit: 10
|
||||||
);
|
);
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -223,6 +223,19 @@ client
|
|||||||
.get();
|
.get();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
using Qdrant.Client;
|
||||||
|
using Qdrant.Client.Grpc;
|
||||||
|
|
||||||
|
var client = new QdrantClient("localhost", 6334);
|
||||||
|
|
||||||
|
await client.CreateCollectionAsync(
|
||||||
|
collectionName: "{collection_name}",
|
||||||
|
vectorsConfig: new VectorParams { Size = 300, Distance = Distance.Cosine },
|
||||||
|
shardNumber: 6
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
We recommend setting the number of shards to be a multiple of the number of nodes you are currently running in your cluster.
|
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.
|
For example, if you have 3 nodes, 6 shards could be a good option.
|
||||||
@@ -324,6 +337,7 @@ client
|
|||||||
collection_name: "{collection_name}".into(),
|
collection_name: "{collection_name}".into(),
|
||||||
shard_number: Some(1),
|
shard_number: Some(1),
|
||||||
sharding_method: Some(ShardingMethod::Custom),
|
sharding_method: Some(ShardingMethod::Custom),
|
||||||
|
// ... other collection parameters
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
.await?;
|
.await?;
|
||||||
@@ -349,6 +363,20 @@ client
|
|||||||
.get();
|
.get();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
using Qdrant.Client;
|
||||||
|
using Qdrant.Client.Grpc;
|
||||||
|
|
||||||
|
var client = new QdrantClient("localhost", 6334);
|
||||||
|
|
||||||
|
await client.CreateCollectionAsync(
|
||||||
|
collectionName: "{collection_name}",
|
||||||
|
// ... other collection parameters
|
||||||
|
shardNumber: 1,
|
||||||
|
shardingMethod: ShardingMethod.Custom
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
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:
|
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
|
```json
|
||||||
@@ -457,6 +485,22 @@ client
|
|||||||
.get();
|
.get();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
using Qdrant.Client;
|
||||||
|
using Qdrant.Client.Grpc;
|
||||||
|
|
||||||
|
var client = new QdrantClient("localhost", 6334);
|
||||||
|
|
||||||
|
await client.UpsertAsync(
|
||||||
|
collectionName: "{collection_name}",
|
||||||
|
points: new List<PointStruct>
|
||||||
|
{
|
||||||
|
new() { Id = 111, Vectors = new[] { 0.1f, 0.2f, 0.3f } }
|
||||||
|
},
|
||||||
|
shardKeySelector: new ShardKeySelector { ShardKeys = { new List<ShardKey> { "user_id" } } }
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
<aside role="alert">
|
<aside role="alert">
|
||||||
Using the same point ID across multiple shard keys is <strong>not supported<sup>*</sup></strong> and should be avoided.
|
Using the same point ID across multiple shard keys is <strong>not supported<sup>*</sup></strong> and should be avoided.
|
||||||
</aside>
|
</aside>
|
||||||
@@ -660,6 +704,20 @@ client
|
|||||||
.get();
|
.get();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
using Qdrant.Client;
|
||||||
|
using Qdrant.Client.Grpc;
|
||||||
|
|
||||||
|
var client = new QdrantClient("localhost", 6334);
|
||||||
|
|
||||||
|
await client.CreateCollectionAsync(
|
||||||
|
collectionName: "{collection_name}",
|
||||||
|
vectorsConfig: new VectorParams { Size = 300, Distance = Distance.Cosine },
|
||||||
|
shardNumber: 6,
|
||||||
|
replicationFactor: 2
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
This code sample creates a collection with a total of 6 logical shards backed by a total of 12 physical shards.
|
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.
|
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.
|
||||||
@@ -889,6 +947,21 @@ client
|
|||||||
.get();
|
.get();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
using Qdrant.Client;
|
||||||
|
using Qdrant.Client.Grpc;
|
||||||
|
|
||||||
|
var client = new QdrantClient("localhost", 6334);
|
||||||
|
|
||||||
|
await client.CreateCollectionAsync(
|
||||||
|
collectionName: "{collection_name}",
|
||||||
|
vectorsConfig: new VectorParams { Size = 300, Distance = Distance.Cosine },
|
||||||
|
shardNumber: 6,
|
||||||
|
replicationFactor: 2,
|
||||||
|
writeConsistencyFactor: 2
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
Write operations will fail if the number of active replicas is less than the `write_consistency_factor`.
|
Write operations will fail if the number of active replicas is less than the `write_consistency_factor`.
|
||||||
|
|
||||||
### Read consistency
|
### Read consistency
|
||||||
@@ -1022,6 +1095,23 @@ client
|
|||||||
.get();
|
.get();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
using Qdrant.Client;
|
||||||
|
using Qdrant.Client.Grpc;
|
||||||
|
using static Qdrant.Client.Grpc.Conditions;
|
||||||
|
|
||||||
|
var client = new QdrantClient("localhost", 6334);
|
||||||
|
|
||||||
|
await client.SearchAsync(
|
||||||
|
collectionName: "{collection_name}",
|
||||||
|
vector: new float[] { 0.2f, 0.1f, 0.9f, 0.7f },
|
||||||
|
filter: MatchKeyword("city", "London"),
|
||||||
|
searchParams: new SearchParams { HnswEf = 128, Exact = true },
|
||||||
|
limit: 3,
|
||||||
|
readConsistency: new ReadConsistency { Type = ReadConsistencyType.Majority }
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
### Write ordering
|
### Write ordering
|
||||||
|
|
||||||
Write `ordering` can be specified for any write request to serialize it through a single "leader" node,
|
Write `ordering` can be specified for any write request to serialize it through a single "leader" node,
|
||||||
@@ -1169,6 +1259,39 @@ client
|
|||||||
.get();
|
.get();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
using Qdrant.Client;
|
||||||
|
using Qdrant.Client.Grpc;
|
||||||
|
|
||||||
|
var client = new QdrantClient("localhost", 6334);
|
||||||
|
|
||||||
|
await client.UpsertAsync(
|
||||||
|
collectionName: "{collection_name}",
|
||||||
|
points: new List<PointStruct>
|
||||||
|
{
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
Id = 1,
|
||||||
|
Vectors = new[] { 0.9f, 0.1f, 0.1f },
|
||||||
|
Payload = { ["city"] = "red" }
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
Id = 2,
|
||||||
|
Vectors = new[] { 0.1f, 0.9f, 0.1f },
|
||||||
|
Payload = { ["city"] = "green" }
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
Id = 3,
|
||||||
|
Vectors = new[] { 0.1f, 0.1f, 0.9f },
|
||||||
|
Payload = { ["city"] = "blue" }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ordering: WriteOrderingType.Strong
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
## Listener mode
|
## Listener mode
|
||||||
|
|
||||||
<aside role="alert">This is an experimental feature, its behavior may change in the future.</aside>
|
<aside role="alert">This is an experimental feature, its behavior may change in the future.</aside>
|
||||||
|
|||||||
@@ -165,6 +165,38 @@ client
|
|||||||
.get();
|
.get();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
using Qdrant.Client;
|
||||||
|
using Qdrant.Client.Grpc;
|
||||||
|
|
||||||
|
var client = new QdrantClient("localhost", 6334);
|
||||||
|
|
||||||
|
await client.UpsertAsync(
|
||||||
|
collectionName: "{collection_name}",
|
||||||
|
points: new List<PointStruct>
|
||||||
|
{
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
Id = 1,
|
||||||
|
Vectors = new[] { 0.9f, 0.1f, 0.1f },
|
||||||
|
Payload = { ["group_id"] = "user_1" }
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
Id = 2,
|
||||||
|
Vectors = new[] { 0.1f, 0.9f, 0.1f },
|
||||||
|
Payload = { ["group_id"] = "user_1" }
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
Id = 3,
|
||||||
|
Vectors = new[] { 0.1f, 0.1f, 0.9f },
|
||||||
|
Payload = { ["group_id"] = "user_2" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
2. Use a filter along with `group_id` to filter vectors for each user.
|
2. Use a filter along with `group_id` to filter vectors for each user.
|
||||||
|
|
||||||
```http
|
```http
|
||||||
@@ -266,6 +298,21 @@ client
|
|||||||
.get();
|
.get();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
using Qdrant.Client;
|
||||||
|
using Qdrant.Client.Grpc;
|
||||||
|
using static Qdrant.Client.Grpc.Conditions;
|
||||||
|
|
||||||
|
var client = new QdrantClient("localhost", 6334);
|
||||||
|
|
||||||
|
await client.SearchAsync(
|
||||||
|
collectionName: "{collection_name}",
|
||||||
|
vector: new float[] { 0.1f, 0.1f, 0.9f },
|
||||||
|
filter: MatchKeyword("group_id", "user_1"),
|
||||||
|
limit: 10
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
## Calibrate performance
|
## 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.
|
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.
|
||||||
@@ -383,6 +430,19 @@ client
|
|||||||
.get();
|
.get();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
using Qdrant.Client;
|
||||||
|
using Qdrant.Client.Grpc;
|
||||||
|
|
||||||
|
var client = new QdrantClient("localhost", 6334);
|
||||||
|
|
||||||
|
await client.CreateCollectionAsync(
|
||||||
|
collectionName: "{collection_name}",
|
||||||
|
vectorsConfig: new VectorParams { Size = 768, Distance = Distance.Cosine },
|
||||||
|
hnswConfig: new HnswConfigDiff { PayloadM = 16, M = 0 }
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
3. Create keyword payload index for `group_id` field.
|
3. Create keyword payload index for `group_id` field.
|
||||||
|
|
||||||
```http
|
```http
|
||||||
@@ -434,10 +494,18 @@ QdrantClient client =
|
|||||||
|
|
||||||
client
|
client
|
||||||
.createPayloadIndexAsync(
|
.createPayloadIndexAsync(
|
||||||
"{collection_name}", "group_id", PayloadSchemaType.Keyword, null, null, null, null)
|
"{collection_name}", "group_id", PayloadSchsemaType.Keyword, null, null, null, null)
|
||||||
.get();
|
.get();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
using Qdrant.Client;
|
||||||
|
|
||||||
|
var client = new QdrantClient("localhost", 6334);
|
||||||
|
|
||||||
|
await client.CreatePayloadIndexAsync(collectionName: "{collection_name}", fieldName: "group_id");
|
||||||
|
```
|
||||||
|
|
||||||
## Limitations
|
## 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.
|
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.
|
||||||
|
|||||||
@@ -161,6 +161,23 @@ client
|
|||||||
.get();
|
.get();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
using Qdrant.Client;
|
||||||
|
using Qdrant.Client.Grpc;
|
||||||
|
|
||||||
|
var client = new QdrantClient("localhost", 6334);
|
||||||
|
|
||||||
|
await client.CreateCollectionAsync(
|
||||||
|
collectionName: "{collection_name}",
|
||||||
|
vectorsConfig: new VectorParams { Size = 768, Distance = Distance.Cosine },
|
||||||
|
optimizersConfig: new OptimizersConfigDiff { MemmapThreshold = 20000 },
|
||||||
|
quantizationConfig: new QuantizationConfig
|
||||||
|
{
|
||||||
|
Scalar = new ScalarQuantization { Type = QuantizationType.Int8, AlwaysRam = true }
|
||||||
|
}
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
`mmmap_threshold` will ensure that vectors will be stored on disk, while `always_ram` will ensure that quantized vectors will be stored in RAM.
|
`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.
|
Optionally, you can disable rescoring with search `params`, which will reduce the number of disk reads even further, but potentially slightly decrease the precision.
|
||||||
@@ -259,6 +276,23 @@ client
|
|||||||
.get();
|
.get();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
using Qdrant.Client;
|
||||||
|
using Qdrant.Client.Grpc;
|
||||||
|
|
||||||
|
var client = new QdrantClient("localhost", 6334);
|
||||||
|
|
||||||
|
await client.SearchAsync(
|
||||||
|
collectionName: "{collection_name}",
|
||||||
|
vector: new float[] { 0.2f, 0.1f, 0.9f, 0.7f },
|
||||||
|
searchParams: new SearchParams
|
||||||
|
{
|
||||||
|
Quantization = new QuantizationSearchParams { Rescore = false }
|
||||||
|
},
|
||||||
|
limit: 3
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
## Prefer high precision with low memory footprint
|
## 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.
|
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.
|
||||||
@@ -377,6 +411,20 @@ client
|
|||||||
.get();
|
.get();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
using Qdrant.Client;
|
||||||
|
using Qdrant.Client.Grpc;
|
||||||
|
|
||||||
|
var client = new QdrantClient("localhost", 6334);
|
||||||
|
|
||||||
|
await client.CreateCollectionAsync(
|
||||||
|
collectionName: "{collection_name}",
|
||||||
|
vectorsConfig: new VectorParams { Size = 768, Distance = Distance.Cosine },
|
||||||
|
optimizersConfig: new OptimizersConfigDiff { MemmapThreshold = 20000 },
|
||||||
|
hnswConfig: new HnswConfigDiff { OnDisk = true }
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
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.
|
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
|
```json
|
||||||
@@ -538,6 +586,23 @@ client
|
|||||||
.get();
|
.get();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
using Qdrant.Client;
|
||||||
|
using Qdrant.Client.Grpc;
|
||||||
|
|
||||||
|
var client = new QdrantClient("localhost", 6334);
|
||||||
|
|
||||||
|
await client.CreateCollectionAsync(
|
||||||
|
collectionName: "{collection_name}",
|
||||||
|
vectorsConfig: new VectorParams { Size = 768, Distance = Distance.Cosine },
|
||||||
|
optimizersConfig: new OptimizersConfigDiff { MemmapThreshold = 20000 },
|
||||||
|
quantizationConfig: new QuantizationConfig
|
||||||
|
{
|
||||||
|
Scalar = new ScalarQuantization { Type = QuantizationType.Int8, AlwaysRam = true }
|
||||||
|
}
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
There are also some search-time parameters you can use to tune the search accuracy and speed:
|
There are also some search-time parameters you can use to tune the search accuracy and speed:
|
||||||
|
|
||||||
```http
|
```http
|
||||||
@@ -625,6 +690,20 @@ client
|
|||||||
.get();
|
.get();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
using Qdrant.Client;
|
||||||
|
using Qdrant.Client.Grpc;
|
||||||
|
|
||||||
|
var client = new QdrantClient("localhost", 6334);
|
||||||
|
|
||||||
|
await client.SearchAsync(
|
||||||
|
collectionName: "{collection_name}",
|
||||||
|
vector: new float[] { 0.2f, 0.1f, 0.9f, 0.7f },
|
||||||
|
searchParams: new SearchParams { HnswEf = 128, Exact = false },
|
||||||
|
limit: 3
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
- `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.
|
- `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.
|
- `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.
|
||||||
|
|
||||||
@@ -740,6 +819,19 @@ client
|
|||||||
.get();
|
.get();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
using Qdrant.Client;
|
||||||
|
using Qdrant.Client.Grpc;
|
||||||
|
|
||||||
|
var client = new QdrantClient("localhost", 6334);
|
||||||
|
|
||||||
|
await client.CreateCollectionAsync(
|
||||||
|
collectionName: "{collection_name}",
|
||||||
|
vectorsConfig: new VectorParams { Size = 768, Distance = Distance.Cosine },
|
||||||
|
optimizersConfig: new OptimizersConfigDiff { DefaultSegmentNumber = 16 }
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
To prefer throughput, you can set up Qdrant to use as many cores as possible for processing multiple requests in parallel.
|
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.
|
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.
|
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.
|
||||||
@@ -845,3 +937,15 @@ client
|
|||||||
.get();
|
.get();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
using Qdrant.Client;
|
||||||
|
using Qdrant.Client.Grpc;
|
||||||
|
|
||||||
|
var client = new QdrantClient("localhost", 6334);
|
||||||
|
|
||||||
|
await client.CreateCollectionAsync(
|
||||||
|
collectionName: "{collection_name}",
|
||||||
|
vectorsConfig: new VectorParams { Size = 768, Distance = Distance.Cosine },
|
||||||
|
optimizersConfig: new OptimizersConfigDiff { DefaultSegmentNumber = 2 }
|
||||||
|
);
|
||||||
|
```
|
||||||
@@ -275,6 +275,27 @@ client
|
|||||||
.get();
|
.get();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
using Qdrant.Client;
|
||||||
|
using Qdrant.Client.Grpc;
|
||||||
|
|
||||||
|
var client = new QdrantClient("localhost", 6334);
|
||||||
|
|
||||||
|
await client.CreateCollectionAsync(
|
||||||
|
collectionName: "{collection_name}",
|
||||||
|
vectorsConfig: new VectorParams { Size = 768, Distance = Distance.Cosine },
|
||||||
|
quantizationConfig: new QuantizationConfig
|
||||||
|
{
|
||||||
|
Scalar = new ScalarQuantization
|
||||||
|
{
|
||||||
|
Type = QuantizationType.Int8,
|
||||||
|
Quantile = 0.99f,
|
||||||
|
AlwaysRam = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
There are 3 parameters that you can specify in the `quantization_config` section:
|
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`.
|
`type` - the type of the quantized vector components. Currently, Qdrant supports only `int8`.
|
||||||
@@ -410,6 +431,22 @@ client
|
|||||||
.get();
|
.get();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
using Qdrant.Client;
|
||||||
|
using Qdrant.Client.Grpc;
|
||||||
|
|
||||||
|
var client = new QdrantClient("localhost", 6334);
|
||||||
|
|
||||||
|
await client.CreateCollectionAsync(
|
||||||
|
collectionName: "{collection_name}",
|
||||||
|
vectorsConfig: new VectorParams { Size = 1536, Distance = Distance.Cosine },
|
||||||
|
quantizationConfig: new QuantizationConfig
|
||||||
|
{
|
||||||
|
Binary = new BinaryQuantization { AlwaysRam = true }
|
||||||
|
}
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
`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.
|
`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.
|
However, in some setups you might want to keep quantized vectors in RAM to speed up the search process.
|
||||||
|
|
||||||
@@ -543,6 +580,22 @@ client
|
|||||||
.get();
|
.get();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
using Qdrant.Client;
|
||||||
|
using Qdrant.Client.Grpc;
|
||||||
|
|
||||||
|
var client = new QdrantClient("localhost", 6334);
|
||||||
|
|
||||||
|
await client.CreateCollectionAsync(
|
||||||
|
collectionName: "{collection_name}",
|
||||||
|
vectorsConfig: new VectorParams { Size = 768, Distance = Distance.Cosine },
|
||||||
|
quantizationConfig: new QuantizationConfig
|
||||||
|
{
|
||||||
|
Product = new ProductQuantization { Compression = CompressionRatio.X16, AlwaysRam = true }
|
||||||
|
}
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
There are two parameters that you can specify in the `quantization_config` section:
|
There are two parameters that you can specify in the `quantization_config` section:
|
||||||
|
|
||||||
`compression` - compression ratio.
|
`compression` - compression ratio.
|
||||||
@@ -669,6 +722,28 @@ client
|
|||||||
.get();
|
.get();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
using Qdrant.Client;
|
||||||
|
using Qdrant.Client.Grpc;
|
||||||
|
|
||||||
|
var client = new QdrantClient("localhost", 6334);
|
||||||
|
|
||||||
|
await client.SearchAsync(
|
||||||
|
collectionName: "{collection_name}",
|
||||||
|
vector: new float[] { 0.2f, 0.1f, 0.9f, 0.7f },
|
||||||
|
searchParams: new SearchParams
|
||||||
|
{
|
||||||
|
Quantization = new QuantizationSearchParams
|
||||||
|
{
|
||||||
|
Ignore = false,
|
||||||
|
Rescore = true,
|
||||||
|
Oversampling = 2.0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
limit: 10
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
`ignore` - Toggle whether to ignore quantized vectors during the search process. By default, Qdrant will use quantized vectors if they are available.
|
`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.
|
`rescore` - Having the original vectors available, Qdrant can re-evaluate top-k search results using the original vectors.
|
||||||
@@ -787,6 +862,23 @@ client
|
|||||||
.get();
|
.get();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
using Qdrant.Client;
|
||||||
|
using Qdrant.Client.Grpc;
|
||||||
|
|
||||||
|
var client = new QdrantClient("localhost", 6334);
|
||||||
|
|
||||||
|
await client.SearchAsync(
|
||||||
|
collectionName: "{collection_name}",
|
||||||
|
vector: new float[] { 0.2f, 0.1f, 0.9f, 0.7f },
|
||||||
|
searchParams: new SearchParams
|
||||||
|
{
|
||||||
|
Quantization = new QuantizationSearchParams { Ignore = true }
|
||||||
|
},
|
||||||
|
limit: 10
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
- **Adjust the quantile parameter**: The quantile parameter in scalar quantization determines the quantization bounds.
|
- **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.
|
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.
|
For example, if you set the quantile to 0.99, 1% of the extreme values will be excluded.
|
||||||
@@ -945,6 +1037,23 @@ client
|
|||||||
.get();
|
.get();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
using Qdrant.Client;
|
||||||
|
using Qdrant.Client.Grpc;
|
||||||
|
|
||||||
|
var client = new QdrantClient("localhost", 6334);
|
||||||
|
|
||||||
|
await client.CreateCollectionAsync(
|
||||||
|
collectionName: "{collection_name}",
|
||||||
|
vectorsConfig: new VectorParams { Size = 768, Distance = Distance.Cosine },
|
||||||
|
optimizersConfig: new OptimizersConfigDiff { MemmapThreshold = 20000 },
|
||||||
|
quantizationConfig: new QuantizationConfig
|
||||||
|
{
|
||||||
|
Scalar = new ScalarQuantization { Type = QuantizationType.Int8, AlwaysRam = true }
|
||||||
|
}
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
In this scenario, the number of disk reads may play a significant role in the search speed.
|
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.
|
In a system with high disk latency, the re-scoring step may become a bottleneck.
|
||||||
|
|
||||||
@@ -1044,6 +1153,23 @@ client
|
|||||||
.get();
|
.get();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
using Qdrant.Client;
|
||||||
|
using Qdrant.Client.Grpc;
|
||||||
|
|
||||||
|
var client = new QdrantClient("localhost", 6334);
|
||||||
|
|
||||||
|
await client.SearchAsync(
|
||||||
|
collectionName: "{collection_name}",
|
||||||
|
vector: new float[] { 0.2f, 0.1f, 0.9f, 0.7f },
|
||||||
|
searchParams: new SearchParams
|
||||||
|
{
|
||||||
|
Quantization = new QuantizationSearchParams { Rescore = false }
|
||||||
|
},
|
||||||
|
limit: 3
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
- **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.
|
- **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).
|
It is recommended to use this mode if you have a large collection and fast storage (e.g. SSD or NVMe).
|
||||||
@@ -1186,4 +1312,21 @@ client
|
|||||||
.build())
|
.build())
|
||||||
.build())
|
.build())
|
||||||
.get();
|
.get();
|
||||||
|
```
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
using Qdrant.Client;
|
||||||
|
using Qdrant.Client.Grpc;
|
||||||
|
|
||||||
|
var client = new QdrantClient("localhost", 6334);
|
||||||
|
|
||||||
|
await client.CreateCollectionAsync(
|
||||||
|
collectionName: "{collection_name}",
|
||||||
|
vectorsConfig: new VectorParams { Size = 768, Distance = Distance.Cosine },
|
||||||
|
optimizersConfig: new OptimizersConfigDiff { MemmapThreshold = 20000 },
|
||||||
|
quantizationConfig: new QuantizationConfig
|
||||||
|
{
|
||||||
|
Scalar = new ScalarQuantization { Type = QuantizationType.Int8, AlwaysRam = false }
|
||||||
|
}
|
||||||
|
);
|
||||||
```
|
```
|
||||||
@@ -79,16 +79,6 @@ const client = new QdrantClient({
|
|||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
```csharp
|
|
||||||
using Qdrant.Client;
|
|
||||||
|
|
||||||
var client = new QdrantClient(
|
|
||||||
"xyz-example.eu-central.aws.cloud.qdrant.io",
|
|
||||||
https: true,
|
|
||||||
apiKey: "<paste-your-api-key-here>"
|
|
||||||
);
|
|
||||||
```
|
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
use qdrant_client::client::QdrantClient;
|
use qdrant_client::client::QdrantClient;
|
||||||
|
|
||||||
@@ -110,6 +100,17 @@ QdrantClient client =
|
|||||||
.withApiKey("<paste-your-api-key-here>")
|
.withApiKey("<paste-your-api-key-here>")
|
||||||
.build());
|
.build());
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
using Qdrant.Client;
|
||||||
|
|
||||||
|
var client = new QdrantClient(
|
||||||
|
host: "xyz-example.eu-central.aws.cloud.qdrant.io",
|
||||||
|
https: true,
|
||||||
|
apiKey: "<paste-your-api-key-here>"
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
<aside role="alert">Internal communication channels are <strong>never</strong> protected by an API key. Internal gRPC uses port 6335 by default if running in distributed mode. You must ensure that this port is not publicly reachable and can only be used for node communication. By default, this setting is disabled for Qdrant Cloud and the Qdrant Helm chart.</aside>
|
<aside role="alert">Internal communication channels are <strong>never</strong> protected by an API key. Internal gRPC uses port 6335 by default if running in distributed mode. You must ensure that this port is not publicly reachable and can only be used for node communication. By default, this setting is disabled for Qdrant Cloud and the Qdrant Helm chart.</aside>
|
||||||
|
|
||||||
### Read-only API key
|
### Read-only API key
|
||||||
|
|||||||
@@ -66,6 +66,12 @@ $tabs-font-color-hover: var(--neutral-n-600);
|
|||||||
mask-image: url("/css/assets/lang-switcher/java.svg");
|
mask-image: url("/css/assets/lang-switcher/java.svg");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
&_csharp {
|
||||||
|
&:before {
|
||||||
|
-webkit-mask-image: url("/css/assets/lang-switcher/csharp.svg");
|
||||||
|
mask-image: url("/css/assets/lang-switcher/csharp.svg");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&:not(.active):hover {
|
&:not(.active):hover {
|
||||||
background: $tabs-bg-color-hover;
|
background: $tabs-bg-color-hover;
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0,0,256,256" width="50px" height="50px"><g fill="#586cac" fill-rule="nonzero" stroke="none" stroke-width="1" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="10" stroke-dasharray="" stroke-dashoffset="0" font-family="none" font-weight="none" font-size="none" text-anchor="none" style="mix-blend-mode: normal"><g transform="scale(5.12,5.12)"><path d="M25,2c-0.71484,0 -1.42969,0.17969 -2.06641,0.53906l-16.84375,9.46484c-1.28906,0.72266 -2.08984,2.07813 -2.08984,3.53125v18.92969c0,1.45313 0.80078,2.80859 2.08984,3.53125l16.84375,9.46484c0.63672,0.35938 1.35156,0.53906 2.06641,0.53906c0.71484,0 1.42969,-0.17969 2.06641,-0.53906l16.84375,-9.46094c1.28906,-0.72656 2.08984,-2.08203 2.08984,-3.53516v-18.92969c0,-1.45312 -0.80078,-2.80859 -2.08984,-3.53125l-16.84375,-9.46484c-0.63672,-0.35937 -1.35156,-0.53906 -2.06641,-0.53906zM25,13c3.78125,0 7.27734,1.75391 9.54297,4.73828l-4.38281,2.53906c-1.31641,-1.44141 -3.1875,-2.27734 -5.16016,-2.27734c-3.85937,0 -7,3.14063 -7,7c0,3.85938 3.14063,7 7,7c1.97266,0 3.84375,-0.83594 5.16016,-2.27734l4.38281,2.53906c-2.26562,2.98438 -5.76172,4.73828 -9.54297,4.73828c-6.61719,0 -12,-5.38281 -12,-12c0,-6.61719 5.38281,-12 12,-12zM35,20h2v2h2v-2h2v2h2v2h-2v2h2v2h-2v2h-2v-2h-2v2h-2v-2h-2v-2h2v-2h-2v-2h2zM37,24v2h2v-2z"></path></g></g></svg>
|
||||||
|
After Width: | Height: | Size: 1.4 KiB |
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user