[1.16] Add ACORN and Inline Storage docs (#1990)

* Add ACORN doc

* Add Inline Storage doc

* Use consistent version gate marker

* Update

---------

Co-authored-by: Tim Visée <tim@visee.me>
This commit is contained in:
xzfc
2025-11-17 15:16:51 +01:00
committed by GitHub
co-authored by Tim Visée
parent 4bf27cb600
commit 69b90aadce
19 changed files with 363 additions and 8 deletions
@@ -0,0 +1,4 @@
When creating a collection with inline storage enabled, the HNSW index stores copies of both the original vectors and quantized vectors within the index file itself.
This reduces random disk seeks during search, trading disk space for improved search speed.
The `inline_storage` option requires quantization to be enabled and does not support multi-vectors.
Set `hnsw_config.inline_storage` to `true` and configure quantization to use this feature.
@@ -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 = 768, Distance = Distance.Cosine, OnDisk = true },
quantizationConfig: new QuantizationConfig
{
Binary = new BinaryQuantization { AlwaysRam = false }
},
hnswConfig: new HnswConfigDiff { OnDisk = true, InlineStorage = true }
);
```
@@ -0,0 +1,30 @@
```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: 768,
Distance: qdrant.Distance_Cosine,
OnDisk: qdrant.PtrOf(true),
}),
QuantizationConfig: qdrant.NewQuantizationBinary(
&qdrant.BinaryQuantization{
AlwaysRam: qdrant.PtrOf(false),
},
),
HnswConfig: &qdrant.HnswConfigDiff{
OnDisk: qdrant.PtrOf(true),
InlineStorage: qdrant.PtrOf(true),
},
})
```
@@ -0,0 +1,19 @@
```http
PUT /collections/{collection_name}
{
"vectors": {
"size": 768,
"distance": "Cosine",
"on_disk": true
},
"quantization_config": {
"binary": {
"always_ram": false
}
},
"hnsw_config": {
"on_disk": true,
"inline_storage": true
}
}
```
@@ -0,0 +1,35 @@
```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.HnswConfigDiff;
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)
.setOnDisk(true)
.build())
.build())
.setQuantizationConfig(
QuantizationConfig.newBuilder()
.setBinary(BinaryQuantization.newBuilder().setAlwaysRam(false).build())
.build())
.setHnswConfig(HnswConfigDiff.newBuilder().setOnDisk(true).setInlineStorage(true).build())
.build())
.get();
```
@@ -0,0 +1,16 @@
```python
from qdrant_client import QdrantClient, models
client = QdrantClient(url="http://localhost:6333")
client.create_collection(
collection_name="{collection_name}",
vectors_config=models.VectorParams(
size=768, distance=models.Distance.COSINE, on_disk=True
),
quantization_config=models.BinaryQuantization(
binary=models.BinaryQuantizationConfig(always_ram=False),
),
hnsw_config=models.HnswConfigDiff(on_disk=True, inline_storage=True),
)
```
@@ -0,0 +1,21 @@
```rust
use qdrant_client::qdrant::{
BinaryQuantizationBuilder, CreateCollectionBuilder, Distance, HnswConfigDiffBuilder,
VectorParamsBuilder,
};
use qdrant_client::Qdrant;
let client = Qdrant::from_url("http://localhost:6334").build()?;
client
.create_collection(
CreateCollectionBuilder::new("{collection_name}")
.vectors_config(VectorParamsBuilder::new(768, Distance::Cosine).on_disk(true))
.quantization_config(BinaryQuantizationBuilder::new(false))
.hnsw_config(
HnswConfigDiffBuilder::default()
.on_disk(true)
.inline_storage(true),
),
)
.await?;
@@ -0,0 +1,22 @@
```typescript
import { QdrantClient } from "@qdrant/js-client-rest";
const client = new QdrantClient({ host: "localhost", port: 6333 });
client.createCollection("{collection_name}", {
vectors: {
size: 768,
distance: "Cosine",
on_disk: true,
},
quantization_config: {
binary: {
always_ram: false,
},
},
hnsw_config: {
on_disk: true,
inline_storage: true,
},
});
```
@@ -0,0 +1,6 @@
This code snippet demonstrates how to enable ACORN for HNSW search.
ACORN improves search recall for searches with multiple low-selectivity payload filters, at the cost of reduced performance.
The `enable` parameter activates ACORN based on filter selectivity.
The `max_selectivity` parameter controls the threshold - if estimated filter selectivity is higher than this value, ACORN will not be used.
Selectivity is estimated as the ratio of points satisfying the filters to total points.
Values range from 0.0 (never use ACORN) to 1.0 (always use ACORN), with a default of 0.4.
@@ -0,0 +1,20 @@
```csharp
using Qdrant.Client;
using Qdrant.Client.Grpc;
var client = new QdrantClient("localhost", 6334);
await client.QueryAsync(
collectionName: "{collection_name}",
query: new float[] { 0.2f, 0.1f, 0.9f, 0.7f },
searchParams: new SearchParams
{
Acorn = new AcornSearchParams
{
Enable = true,
MaxSelectivity = 0.4
}
},
limit: 10
);
```
@@ -0,0 +1,23 @@
```go
import (
"context"
"github.com/qdrant/go-client/qdrant"
)
client, err := qdrant.NewClient(&qdrant.Config{
Host: "localhost",
Port: 6334,
})
client.Query(context.Background(), &qdrant.QueryPoints{
CollectionName: "{collection_name}",
Query: qdrant.NewQuery(0.2, 0.1, 0.9, 0.7),
Params: &qdrant.SearchParams{
Acorn: &qdrant.AcornSearchParams{
Enable: qdrant.PtrOf(true),
MaxSelectivity: qdrant.PtrOf(0.4),
},
},
})
```
@@ -0,0 +1,13 @@
```http
POST /collections/{collection_name}/points/query
{
"query": [0.2, 0.1, 0.9, 0.7],
"params": {
"acorn": {
"enable": true,
"max_selectivity": 0.4
}
},
"limit": 10
}
```
@@ -0,0 +1,28 @@
```java
import io.qdrant.client.QdrantClient;
import io.qdrant.client.QdrantGrpcClient;
import io.qdrant.client.grpc.Points.AcornSearchParams;
import io.qdrant.client.grpc.Points.QueryPoints;
import io.qdrant.client.grpc.Points.SearchParams;
import static io.qdrant.client.QueryFactory.nearest;
QdrantClient client =
new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
client.queryAsync(
QueryPoints.newBuilder()
.setCollectionName("{collection_name}")
.setQuery(nearest(0.2f, 0.1f, 0.9f, 0.7f))
.setParams(
SearchParams.newBuilder()
.setAcorn(
AcornSearchParams.newBuilder()
.setEnable(true)
.setMaxSelectivity(0.4)
.build())
.build())
.setLimit(10)
.build())
.get();
```
@@ -0,0 +1,17 @@
```python
from qdrant_client import QdrantClient, models
client = QdrantClient(url="http://localhost:6333")
client.query_points(
collection_name="{collection_name}",
query=[0.2, 0.1, 0.9, 0.7],
search_params=models.SearchParams(
acorn=models.AcornSearchParams(
enable=True,
max_selectivity=0.4,
)
),
limit=10,
)
```
@@ -0,0 +1,22 @@
```rust
use qdrant_client::qdrant::{
AcornSearchParamsBuilder, QueryPointsBuilder, SearchParamsBuilder,
};
use qdrant_client::Qdrant;
let client = Qdrant::from_url("http://localhost:6334").build()?;
client
.query(
QueryPointsBuilder::new("{collection_name}")
.query(vec![0.2, 0.1, 0.9, 0.7])
.limit(10)
.params(
SearchParamsBuilder::default().acorn(
AcornSearchParamsBuilder::new(true)
.max_selectivity(0.4),
),
),
)
.await?;
```
@@ -0,0 +1,16 @@
```typescript
import { QdrantClient } from "@qdrant/js-client-rest";
const client = new QdrantClient({ host: "localhost", port: 6333 });
client.query("{collection_name}", {
query: [0.2, 0.1, 0.9, 0.7],
params: {
acorn: {
enable: true,
max_selectivity: 0.4,
},
},
limit: 10,
});
```