[v1.16] Collection metadata docs (#1986)

* wip: initial docs

* docs: Go snippets

Signed-off-by: Anush008 <anushshetty90@gmail.com>

* docs: Java snippets

Signed-off-by: Anush008 <anushshetty90@gmail.com>

* docs: Removed TODO!

Signed-off-by: Anush008 <anushshetty90@gmail.com>

* docs: C# snippets

Signed-off-by: Anush008 <anushshetty90@gmail.com>

* move collection metadata section into collection info

* fix code fence mismatch in markdown

* Remove empty line

---------

Signed-off-by: Anush008 <anushshetty90@gmail.com>
Co-authored-by: Anush008 <anushshetty90@gmail.com>
Co-authored-by: trean <trean.mi@gmail.com>
Co-authored-by: Tim Visée <tim@visee.me>
This commit is contained in:
Andrey Vasnetsov
2025-11-17 15:02:57 +01:00
committed by GitHub
co-authored by Anush008 trean Tim Visée
parent be24d900ef
commit 5ed4822559
20 changed files with 328 additions and 6 deletions
@@ -334,6 +334,42 @@ created and `indexed_vectors_count` might be equal to `0`.
It is possible to reduce the `indexing_threshold` for an existing collection by [updating collection parameters](#update-collection-parameters). It is possible to reduce the `indexing_threshold` for an existing collection by [updating collection parameters](#update-collection-parameters).
### Collection metadata
*Available as of v1.16.0*
For convenience and better data organization, Qdrant allows attaching custom metadata to collections in the form of key-value pairs.
Adding metadata is treated as a part of collection configuration and synchronized across all nodes in a cluster with consensus protocol.
Collection metadata can be specified during collection creation:
{{< code-snippet path="/documentation/headless/snippets/create-collection/with-metadata/" >}}
as well as updated later:
{{< code-snippet path="/documentation/headless/snippets/update-collection/with-metadata/" >}}
Note, that update operation only modifies the specified metadata fields, leaving other fields unchanged.
When specified, metadata is returned as part of collection info:
``` json
{
"result": {
"config": {
"metadata": {
"my-metadata-field": {
"key-a": "value-a",
"key-b": 42
},
"another-field": 123
}
}
}
}
```
## Collection aliases ## Collection aliases
In a production environment, it is sometimes necessary to switch different versions of vectors seamlessly. In a production environment, it is sometimes necessary to switch different versions of vectors seamlessly.
@@ -372,3 +408,4 @@ For example, you can switch underlying collection with the following command:
### List all collections ### List all collections
{{< code-snippet path="/documentation/headless/snippets/list-all-collections/simple/" >}} {{< code-snippet path="/documentation/headless/snippets/list-all-collections/simple/" >}}
@@ -0,0 +1 @@
This code snippet is used to create a collection with a specific vector configuration and additional metadata. The metadata is provided as a JSON object, allowing you to store custom information about the collection. In this example, we add two metadata fields.
@@ -0,0 +1,14 @@
```bash
curl -X PUT http://localhost:6333/collections/{collection_name} \
-H 'Content-Type: application/json' \
--data-raw '{
"vectors": {
"size": 300,
"distance": "Cosine"
},
"metadata": {
"my-metadata-field": "value-1",
"another-field": 123
}
}'
```
@@ -0,0 +1,16 @@
```csharp
using Qdrant.Client;
using Qdrant.Client.Grpc;
var client = new QdrantClient("localhost", 6334);
await client.CreateCollectionAsync(
collectionName: "{collection_name}",
vectorsConfig: new VectorParams { Size = 100, Distance = Distance.Cosine },
metadata: new()
{
["my-metadata-field"] = "value-1",
["another-field"] = 123
}
);
```
@@ -0,0 +1,24 @@
```go
import (
"context"
"github.com/qdrant/go-client/qdrant"
)
client, err := qdrant.NewClient(&qdrant.Config{
Host: "localhost",
Port: 6334,
})
client.CreateCollection(context.Background(), &qdrant.CreateCollection{
CollectionName: "{collection_name}",
VectorsConfig: qdrant.NewVectorsConfig(&qdrant.VectorParams{
Size: 100,
Distance: qdrant.Distance_Cosine,
}),
Metadata: qdrant.NewValueMap(map[string]any{
"my-metadata-field": "value-1",
"another-field": 123,
}),
})
```
@@ -0,0 +1,13 @@
```http
PUT /collections/{collection_name}
{
"vectors": {
"size": 300,
"distance": "Cosine"
},
"metadata": {
"my-metadata-field": "value-1",
"another-field": 123
}
}
```
@@ -0,0 +1,34 @@
```java
import java.util.Map;
import static io.qdrant.client.ValueFactory.value;
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;
import io.qdrant.client.QdrantClient;
import io.qdrant.client.QdrantGrpcClient;
QdrantClient client = new QdrantClient(
QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
client
.createCollectionAsync(
CreateCollection.newBuilder()
.setCollectionName("{collection_name}")
.setVectorsConfig(
VectorsConfig.newBuilder()
.setParams(
VectorParams.newBuilder()
.setDistance(Distance.Cosine)
.setSize(100)
.build())
.build())
.putAllMetadata(
Map.of(
"my-metadata-field", value("value-1"),
"another-field", value(123)))
.build())
.get();
```
@@ -0,0 +1,13 @@
```python
from qdrant_client import QdrantClient, models
client = QdrantClient(url="http://localhost:6333")
client.create_collection(
collection_name="{collection_name}",
metadata={
"my-metadata-field": "value-1",
"another-field": 123
},
)
```
@@ -0,0 +1,22 @@
```rust
use qdrant_client::qdrant::{CreateCollectionBuilder, Distance, VectorParamsBuilder};
use qdrant_client::Qdrant;
use serde_json::{json, Value};
use std::collections::HashMap;
let client = Qdrant::from_url("http://localhost:6334").build()?;
let mut metadata: HashMap<String, Value> = HashMap::new();
metadata.insert("my-metadata-field".to_string(), json!("value-1"));
metadata.insert("another-field".to_string(), json!(123));
client
.create_collection(
CreateCollectionBuilder::new("{collection_name}")
.vectors_config(VectorParamsBuilder::new(100, Distance::Cosine))
.metadata(metadata),
)
.await?;
```
@@ -0,0 +1,13 @@
```typescript
import { QdrantClient } from "@qdrant/js-client-rest";
const client = new QdrantClient({ host: "localhost", port: 6333 });
client.createCollection("{collection_name}", {
vectors: { size: 100, distance: "Cosine" },
metadata: {
"my-metadata-field": "value-1",
"another-field": 123
}
});
```
@@ -2,10 +2,12 @@
import io.qdrant.client.grpc.Collections.OptimizersConfigDiff; import io.qdrant.client.grpc.Collections.OptimizersConfigDiff;
import io.qdrant.client.grpc.Collections.UpdateCollection; import io.qdrant.client.grpc.Collections.UpdateCollection;
client.updateCollectionAsync( client
.updateCollectionAsync(
UpdateCollection.newBuilder() UpdateCollection.newBuilder()
.setCollectionName("{collection_name}") .setCollectionName("{collection_name}")
.setOptimizersConfig( .setOptimizersConfig(
OptimizersConfigDiff.newBuilder().setIndexingThreshold(10000).build()) OptimizersConfigDiff.newBuilder().setIndexingThreshold(10000).build())
.build()); .build())
.get();
``` ```
@@ -0,0 +1 @@
Update collection metadata. This example demonstrates how to overwrite a specific field in the collection's metadata while leaving other fields unchanged. Collection metadata can be any JSON object that provides additional information about the collection.
@@ -0,0 +1,12 @@
```bash
curl -X PATCH http://localhost:6333/collections/{collection_name} \
-H 'Content-Type: application/json' \
--data-raw '{
"metadata": {
"my-metadata-field": {
"key-a": "value-a",
"key-b": 42
}
}
}'
```
@@ -0,0 +1,19 @@
```csharp
using Qdrant.Client;
using Qdrant.Client.Grpc;
var client = new QdrantClient("localhost", 6334);
await client.UpdateCollectionAsync(
collectionName: "{collection_name}",
optimizersConfig: new OptimizersConfigDiff { IndexingThreshold = 10000 },
metadata: new()
{
["my-metadata-field"] = new Dictionary<string, Value>
{
["key-a"] = "value-a",
["key-b"] = 42
},
}
);
```
@@ -0,0 +1,25 @@
```go
import (
"context"
"github.com/qdrant/go-client/qdrant"
)
client, err := qdrant.NewClient(&qdrant.Config{
Host: "localhost",
Port: 6334,
})
client.UpdateCollection(context.Background(), &qdrant.UpdateCollection{
CollectionName: "{collection_name}",
OptimizersConfig: &qdrant.OptimizersConfigDiff{
IndexingThreshold: qdrant.PtrOf(uint64(10000)),
},
Metadata: qdrant.NewValueMap(map[string]any{
"my-metadata-field": map[string]any{
"key-a": "value-a",
"key-b": 42,
},
}),
})
```
@@ -0,0 +1,11 @@
```http
PATCH /collections/{collection_name}
{
"metadata": {
"my-metadata-field": {
"key-a": "value-a",
"key-b": 42
}
}
}
```
@@ -0,0 +1,24 @@
```java
import java.util.Map;
import static io.qdrant.client.ValueFactory.value;
import io.qdrant.client.grpc.Collections.OptimizersConfigDiff;
import io.qdrant.client.grpc.Collections.UpdateCollection;
client
.updateCollectionAsync(
UpdateCollection.newBuilder()
.setCollectionName("{collection_name}")
.setOptimizersConfig(
OptimizersConfigDiff.newBuilder().setIndexingThreshold(10000).build())
.putAllMetadata(
Map.of(
"my-metadata-field",
value(
Map.of(
"key-a", value("value-a"),
"key-b", value(42)))))
.build())
.get();
```
@@ -0,0 +1,11 @@
```python
client.update_collection(
collection_name="{collection_name}",
metadata={
"my-metadata-field": {
"key-a": "value-a",
"key-b": 42
}
},
)
```
@@ -0,0 +1,20 @@
```rust
use qdrant_client::qdrant::{UpdateCollectionBuilder};
use qdrant_client::Qdrant;
use serde_json::{json, Value};
use std::collections::HashMap;
let client = Qdrant::from_url("http://localhost:6334").build()?;
let mut metadata: HashMap<String, Value> = HashMap::new();
metadata.insert("my-metadata-field".to_string(), json!({
"key-a": "value-a",
"key-b": 42
}));
client
.update_collection(
UpdateCollectionBuilder::new("{collection_name}").metadata(metadata),
)
.await?;
```
@@ -0,0 +1,10 @@
```typescript
client.updateCollection("{collection_name}", {
metadata: {
"my-metadata-field": {
"key-a": "value-a",
"key-b": 42
}
},
});
```