diff --git a/qdrant-landing/content/documentation/concepts/collections.md b/qdrant-landing/content/documentation/concepts/collections.md index edf53f0d8..d4c5cb4c3 100644 --- a/qdrant-landing/content/documentation/concepts/collections.md +++ b/qdrant-landing/content/documentation/concepts/collections.md @@ -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). +### 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 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 {{< code-snippet path="/documentation/headless/snippets/list-all-collections/simple/" >}} + diff --git a/qdrant-landing/content/documentation/headless/snippets/create-collection/with-metadata/_description.md b/qdrant-landing/content/documentation/headless/snippets/create-collection/with-metadata/_description.md new file mode 100644 index 000000000..2884b2180 --- /dev/null +++ b/qdrant-landing/content/documentation/headless/snippets/create-collection/with-metadata/_description.md @@ -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. \ No newline at end of file diff --git a/qdrant-landing/content/documentation/headless/snippets/create-collection/with-metadata/bash.md b/qdrant-landing/content/documentation/headless/snippets/create-collection/with-metadata/bash.md new file mode 100644 index 000000000..20f9caad5 --- /dev/null +++ b/qdrant-landing/content/documentation/headless/snippets/create-collection/with-metadata/bash.md @@ -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 + } + }' +``` diff --git a/qdrant-landing/content/documentation/headless/snippets/create-collection/with-metadata/csharp.md b/qdrant-landing/content/documentation/headless/snippets/create-collection/with-metadata/csharp.md new file mode 100644 index 000000000..5903dbd79 --- /dev/null +++ b/qdrant-landing/content/documentation/headless/snippets/create-collection/with-metadata/csharp.md @@ -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 + } +); +``` diff --git a/qdrant-landing/content/documentation/headless/snippets/create-collection/with-metadata/go.md b/qdrant-landing/content/documentation/headless/snippets/create-collection/with-metadata/go.md new file mode 100644 index 000000000..b1603e377 --- /dev/null +++ b/qdrant-landing/content/documentation/headless/snippets/create-collection/with-metadata/go.md @@ -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, + }), +}) +``` diff --git a/qdrant-landing/content/documentation/headless/snippets/create-collection/with-metadata/http.md b/qdrant-landing/content/documentation/headless/snippets/create-collection/with-metadata/http.md new file mode 100644 index 000000000..74f2b7474 --- /dev/null +++ b/qdrant-landing/content/documentation/headless/snippets/create-collection/with-metadata/http.md @@ -0,0 +1,13 @@ +```http +PUT /collections/{collection_name} +{ + "vectors": { + "size": 300, + "distance": "Cosine" + }, + "metadata": { + "my-metadata-field": "value-1", + "another-field": 123 + } +} +``` diff --git a/qdrant-landing/content/documentation/headless/snippets/create-collection/with-metadata/java.md b/qdrant-landing/content/documentation/headless/snippets/create-collection/with-metadata/java.md new file mode 100644 index 000000000..d367eada9 --- /dev/null +++ b/qdrant-landing/content/documentation/headless/snippets/create-collection/with-metadata/java.md @@ -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(); +``` diff --git a/qdrant-landing/content/documentation/headless/snippets/create-collection/with-metadata/python.md b/qdrant-landing/content/documentation/headless/snippets/create-collection/with-metadata/python.md new file mode 100644 index 000000000..09712990b --- /dev/null +++ b/qdrant-landing/content/documentation/headless/snippets/create-collection/with-metadata/python.md @@ -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 + }, +) +``` \ No newline at end of file diff --git a/qdrant-landing/content/documentation/headless/snippets/create-collection/with-metadata/rust.md b/qdrant-landing/content/documentation/headless/snippets/create-collection/with-metadata/rust.md new file mode 100644 index 000000000..325307d5c --- /dev/null +++ b/qdrant-landing/content/documentation/headless/snippets/create-collection/with-metadata/rust.md @@ -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 = 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?; +``` diff --git a/qdrant-landing/content/documentation/headless/snippets/create-collection/with-metadata/typescript.md b/qdrant-landing/content/documentation/headless/snippets/create-collection/with-metadata/typescript.md new file mode 100644 index 000000000..12cc53a59 --- /dev/null +++ b/qdrant-landing/content/documentation/headless/snippets/create-collection/with-metadata/typescript.md @@ -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 + } +}); +``` diff --git a/qdrant-landing/content/documentation/headless/snippets/update-collection/simple/java.md b/qdrant-landing/content/documentation/headless/snippets/update-collection/simple/java.md index 3cecb9754..25c4b79d5 100644 --- a/qdrant-landing/content/documentation/headless/snippets/update-collection/simple/java.md +++ b/qdrant-landing/content/documentation/headless/snippets/update-collection/simple/java.md @@ -2,10 +2,12 @@ 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()) - .build()); +client + .updateCollectionAsync( + UpdateCollection.newBuilder() + .setCollectionName("{collection_name}") + .setOptimizersConfig( + OptimizersConfigDiff.newBuilder().setIndexingThreshold(10000).build()) + .build()) + .get(); ``` diff --git a/qdrant-landing/content/documentation/headless/snippets/update-collection/with-metadata/_description.md b/qdrant-landing/content/documentation/headless/snippets/update-collection/with-metadata/_description.md new file mode 100644 index 000000000..5ab907f5c --- /dev/null +++ b/qdrant-landing/content/documentation/headless/snippets/update-collection/with-metadata/_description.md @@ -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. \ No newline at end of file diff --git a/qdrant-landing/content/documentation/headless/snippets/update-collection/with-metadata/bash.md b/qdrant-landing/content/documentation/headless/snippets/update-collection/with-metadata/bash.md new file mode 100644 index 000000000..3891ae402 --- /dev/null +++ b/qdrant-landing/content/documentation/headless/snippets/update-collection/with-metadata/bash.md @@ -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 + } + } + }' +``` diff --git a/qdrant-landing/content/documentation/headless/snippets/update-collection/with-metadata/csharp.md b/qdrant-landing/content/documentation/headless/snippets/update-collection/with-metadata/csharp.md new file mode 100644 index 000000000..252501f00 --- /dev/null +++ b/qdrant-landing/content/documentation/headless/snippets/update-collection/with-metadata/csharp.md @@ -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 + { + ["key-a"] = "value-a", + ["key-b"] = 42 + }, + } +); +``` diff --git a/qdrant-landing/content/documentation/headless/snippets/update-collection/with-metadata/go.md b/qdrant-landing/content/documentation/headless/snippets/update-collection/with-metadata/go.md new file mode 100644 index 000000000..fec662b27 --- /dev/null +++ b/qdrant-landing/content/documentation/headless/snippets/update-collection/with-metadata/go.md @@ -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, + }, + }), +}) +``` diff --git a/qdrant-landing/content/documentation/headless/snippets/update-collection/with-metadata/http.md b/qdrant-landing/content/documentation/headless/snippets/update-collection/with-metadata/http.md new file mode 100644 index 000000000..77b96da39 --- /dev/null +++ b/qdrant-landing/content/documentation/headless/snippets/update-collection/with-metadata/http.md @@ -0,0 +1,11 @@ +```http +PATCH /collections/{collection_name} +{ + "metadata": { + "my-metadata-field": { + "key-a": "value-a", + "key-b": 42 + } + } +} +``` diff --git a/qdrant-landing/content/documentation/headless/snippets/update-collection/with-metadata/java.md b/qdrant-landing/content/documentation/headless/snippets/update-collection/with-metadata/java.md new file mode 100644 index 000000000..385470bba --- /dev/null +++ b/qdrant-landing/content/documentation/headless/snippets/update-collection/with-metadata/java.md @@ -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(); +``` diff --git a/qdrant-landing/content/documentation/headless/snippets/update-collection/with-metadata/python.md b/qdrant-landing/content/documentation/headless/snippets/update-collection/with-metadata/python.md new file mode 100644 index 000000000..644333a88 --- /dev/null +++ b/qdrant-landing/content/documentation/headless/snippets/update-collection/with-metadata/python.md @@ -0,0 +1,11 @@ +```python +client.update_collection( + collection_name="{collection_name}", + metadata={ + "my-metadata-field": { + "key-a": "value-a", + "key-b": 42 + } + }, +) +``` diff --git a/qdrant-landing/content/documentation/headless/snippets/update-collection/with-metadata/rust.md b/qdrant-landing/content/documentation/headless/snippets/update-collection/with-metadata/rust.md new file mode 100644 index 000000000..fd4dd0817 --- /dev/null +++ b/qdrant-landing/content/documentation/headless/snippets/update-collection/with-metadata/rust.md @@ -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 = 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?; +``` diff --git a/qdrant-landing/content/documentation/headless/snippets/update-collection/with-metadata/typescript.md b/qdrant-landing/content/documentation/headless/snippets/update-collection/with-metadata/typescript.md new file mode 100644 index 000000000..7fe5ef471 --- /dev/null +++ b/qdrant-landing/content/documentation/headless/snippets/update-collection/with-metadata/typescript.md @@ -0,0 +1,10 @@ +```typescript +client.updateCollection("{collection_name}", { + metadata: { + "my-metadata-field": { + "key-a": "value-a", + "key-b": 42 + } + }, +}); +```