Алиасы коллекций#

В производственной среде иногда возникает необходимость бесшовного переключения между разными версиями векторов. Например, при переходе на новую версию нейронной сети.

В таких ситуациях нет возможности остановить сервис и заново построить коллекцию с новыми векторами. Алиасы — это альтернативные имена (псевдонимы) для существующих коллекций. Все запросы к коллекции могут быть выполнены идентично, используя вместо имени коллекции ее псевдоним.

Таким образом, можно построить вторую коллекцию в фоне и затем переключить псевдоним со старой коллекцию на новую. Поскольку изменение псевдонимов происходит атомарно, никакие параллельные запросы не пострадают во время переключения.

Предусловия#

  1. Существует коллекция example_collection.

  2. Установлен клиентский SDK или присутствует доступ к HTTP/REST API Qdrant.

Последовательность выполнения#

  1. Создание псевдонима

    POST /collections/aliases
    {
        "actions": [
            {
                "create_alias": {
                    "collection_name": "example_collection",
                    "alias_name": "production_collection"
                }
            }
        ]
    }
    
    curl -X POST http://localhost:6333/collections/aliases \
      -H 'Content-Type: application/json' \
      --data-raw '{
        "actions": [
            {
                "create_alias": {
                    "collection_name": "example_collection",
                    "alias_name": "production_collection"
                }
            }
        ]
    }'
    
    client.update_collection_aliases(
        change_aliases_operations=[
            models.CreateAliasOperation(
                create_alias=models.CreateAlias(
                    collection_name="example_collection", alias_name="production_collection"
                )
            )
        ]
    )
    
    client.updateCollectionAliases({
      actions: [
        {
          create_alias: {
            collection_name: "example_collection",
            alias_name: "production_collection",
          },
        },
      ],
    });
    
    use qdrant_client::qdrant::CreateAliasBuilder;
    
    client
        .create_alias(CreateAliasBuilder::new(
            "example_collection",
            "production_collection",
        ))
        .await?;
    
    client.createAliasAsync("production_collection", "example_collection").get();
    
    await client.CreateAliasAsync(aliasName: "production_collection", collectionName: "example_collection");
    
    import "context"
    
    client.CreateAlias(context.Background(), "production_collection", "example_collection")
    
  2. Удаление псевдонима

    POST /collections/aliases
    {
        "actions": [
            {
                "delete_alias": {
                    "alias_name": "production_collection"
                }
            }
        ]
    }
    
    curl -X POST http://localhost:6333/collections/aliases \
      -H 'Content-Type: application/json' \
      --data-raw '{
        "actions": [
            {
                "delete_alias": {
                    "alias_name": "production_collection"
                }
            }
        ]
    }'
    
    client.update_collection_aliases(
        change_aliases_operations=[
            models.DeleteAliasOperation(
                delete_alias=models.DeleteAlias(alias_name="production_collection")
            ),
        ]
    )
    
    client.updateCollectionAliases({
      actions: [
        {
          delete_alias: {
            alias_name: "production_collection",
          },
        },
      ],
    });
    
    client.delete_alias("production_collection").await?;
    
    client.deleteAliasAsync("production_collection").get();
    
    await client.DeleteAliasAsync("production_collection");
    
    import "context"
    
    client.DeleteAlias(context.Background(), "production_collection")
    
  3. Смена коллекции: несколько действий с псевдонимами выполняются атомарно. Например, можно сменить базовую коллекцию следующей командой:

    POST /collections/aliases
    {
        "actions": [
            {
                "delete_alias": {
                    "alias_name": "production_collection"
                }
            },
            {
                "create_alias": {
                    "collection_name": "example_collection",
                    "alias_name": "production_collection"
                }
            }
        ]
    }
    
    curl -X POST http://localhost:6333/collections/aliases \
      -H 'Content-Type: application/json' \
      --data-raw '{
        "actions": [
            {
                "delete_alias": {
                    "alias_name": "production_collection"
                }
            },
            {
                "create_alias": {
                    "collection_name": "example_collection",
                    "alias_name": "production_collection"
                }
            }
        ]
    }'
    
    client.update_collection_aliases(
        change_aliases_operations=[
            models.DeleteAliasOperation(
                delete_alias=models.DeleteAlias(alias_name="production_collection")
            ),
            models.CreateAliasOperation(
                create_alias=models.CreateAlias(
                    collection_name="example_collection", alias_name="production_collection"
                )
            ),
        ]
    )
    
    client.updateCollectionAliases({
      actions: [
        {
          delete_alias: {
            alias_name: "production_collection",
          },
        },
        {
          create_alias: {
            collection_name: "example_collection",
            alias_name: "production_collection",
          },
        },
      ],
    });
    
    use qdrant_client::qdrant::CreateAliasBuilder;
    
    client.delete_alias("production_collection").await?;
    client
        .create_alias(CreateAliasBuilder::new(
            "example_collection",
            "production_collection",
        ))
        .await?;
    
    client.deleteAliasAsync("production_collection").get();
    client.createAliasAsync("production_collection", "example_collection").get();
    
    await client.DeleteAliasAsync("production_collection");
    await client.CreateAliasAsync(aliasName: "production_collection", collectionName: "example_collection");
    
    import "context"
    
    client.DeleteAlias(context.Background(), "production_collection")
    client.CreateAlias(context.Background(), "production_collection", "example_collection")
    
  4. Получение списка псевдонимов коллекции:

    GET /collections/{collection_name}/aliases
    
    curl -X GET http://localhost:6333/collections/{collection_name}/aliases
    
    from qdrant_client import QdrantClient
    
    client = QdrantClient(url="http://localhost:6333")
    
    client.get_collection_aliases(collection_name="{collection_name}")
    
    import { QdrantClient } from "@qdrant/js-client-rest";
    
    const client = new QdrantClient({ host: "localhost", port: 6333 });
    
    client.getCollectionAliases("{collection_name}");
    
    use qdrant_client::Qdrant;
    
    let client = Qdrant::from_url("http://localhost:6334").build()?;
    
    client.list_collection_aliases("{collection_name}").await?;
    
    import io.qdrant.client.QdrantClient;
    import io.qdrant.client.QdrantGrpcClient;
    
    QdrantClient client =
        new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
    
    client.listCollectionAliasesAsync("{collection_name}").get();
    
    using Qdrant.Client;
    
    var client = new QdrantClient("localhost", 6334);
    
    await client.ListCollectionAliasesAsync("{collection_name}");
    
    import (
      "context"
    
      "github.com/qdrant/go-client/qdrant"
    )
    
    client, err := qdrant.NewClient(&qdrant.Config{
      Host: "localhost",
      Port: 6334,
    })
    
    client.ListCollectionAliases(context.Background(), "{collection_name}")
    
  5. Получение всех псевдонимов:

    GET /aliases
    
    curl -X GET http://localhost:6333/aliases
    
    from qdrant_client import QdrantClient
    
    client = QdrantClient(url="http://localhost:6333")
    
    client.get_aliases()
    
    import { QdrantClient } from "@qdrant/js-client-rest";
    
    const client = new QdrantClient({ host: "localhost", port: 6333 });
    
    client.getAliases();
    
    use qdrant_client::Qdrant;
    
    let client = Qdrant::from_url("http://localhost:6334").build()?;
    
    client.list_aliases().await?;
    
    import io.qdrant.client.QdrantClient;
    import io.qdrant.client.QdrantGrpcClient;
    
    QdrantClient client =
        new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
    
    client.listAliasesAsync().get();
    
    using Qdrant.Client;
    
    var client = new QdrantClient("localhost", 6334);
    
    await client.ListAliasesAsync();
    
    import (
      "context"
    
      "github.com/qdrant/go-client/qdrant"
    )
    
    client, err := qdrant.NewClient(&qdrant.Config{
      Host: "localhost",
      Port: 6334,
    })
    
    client.ListAliases(context.Background())
    
  6. Получение всех коллекций:

GET /collections
curl -X GET http://localhost:6333/collections
from qdrant_client import QdrantClient

client = QdrantClient(url="http://localhost:6333")

client.get_collections()
import { QdrantClient } from "@qdrant/js-client-rest";

const client = new QdrantClient({ host: "localhost", port: 6333 });

client.getCollections();
use qdrant_client::Qdrant;

let client = Qdrant::from_url("http://localhost:6334").build()?;

client.list_collections().await?;
import io.qdrant.client.QdrantClient;
import io.qdrant.client.QdrantGrpcClient;

QdrantClient client =
    new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());

client.listCollectionsAsync().get();
using Qdrant.Client;

var client = new QdrantClient("localhost", 6334);

await client.ListCollectionsAsync();
import (
  "context"

  "github.com/qdrant/go-client/qdrant"
)

client, err := qdrant.NewClient(&qdrant.Config{
  Host: "localhost",
  Port: 6334,
})

client.ListCollections(context.Background())

Результат#

Псевдоним production_collection будет связан с коллекцией example_collection. Запросы к production_collection будут перенаправлены на example_collection.