• О компании Milvus
  • Начать работу
  • Понятия
  • Руководство пользователя
  • Импорт данных
  • Инструменты искусственного интеллекта
  • Руководство по администрированию
  • Инструменты
  • Интеграции
  • Учебные материалы
  • Часто задаваемые вопросы
  • API Reference

BITMAP

Битовая индексация — это эффективный метод индексирования, предназначенный для повышения производительности запросов по скалярным полям с низкой кардинальностью. Кардинальность — это количество различных значений в поле. Поля с небольшим количеством различных элементов считаются полями с низкой кардинальностью.

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

Обзор

Термин «битовая карта» (Bitmap) объединяет два слова: «бит» (Bit) и «карта» (Map). Бит представляет собой наименьшую единицу данных в компьютере, которая может принимать только значение 0 или 1. Карта в данном контексте означает процесс преобразования и организации данных в соответствии с тем, какое значение следует присвоить 0 и 1.

Битовый индекс состоит из двух основных компонентов: битовых карт и ключей. Ключи представляют собой уникальные значения в индексируемом поле. Для каждого уникального значения существует соответствующая битовая карта. Длина этих битовых карт равна количеству записей в коллекции. Каждый бит в растровой карте соответствует одной записи в коллекции. Если значение индексируемого поля в записи совпадает с ключом, соответствующий бит устанавливается в 1; в противном случае — в 0.

Рассмотрим коллекцию документов с полями «Категория» и «Доступно для общественности». Нам нужно извлечь документы, относящиеся к категории «Технологии » и доступные для общественности. В этом случае ключами для наших растровых индексов являются «Технологии » и «Доступно для общественности».

Bitmap Битовая карта

Как показано на рисунке, битовые индексы для полей «Category» и «Public» имеют следующий вид:

  • «Tech»: [1, 0, 1, 0, 0], что показывает, что только 1-й и 3-й документы относятся к категории «Tech ».

  • Public: [1, 0, 0, 1, 0], что показывает, что только первый и четвёртый документы доступны для общественности.

Чтобы найти документы, соответствующие обоим критериям, мы выполняем побитовую операцию «И» над этими двумя битовыми картами:

  • «Tech» И «Public»: [1, 0, 0, 0, 0]

Полученная битовая карта [1, 0, 0, 0, 0] указывает, что только первый документ (ID 1) удовлетворяет обоим критериям. Используя битовые индексы и эффективные битовые операции, мы можем быстро сузить область поиска, избавившись от необходимости сканировать весь набор данных.

Создание битового индекса

Чтобы создать растровый индекс в Milvus, воспользуйтесь методом ` create_index() ` и установите для параметра ` index_type ` значение ` "BITMAP"`.

from pymilvus import MilvusClient

client = MilvusClient(
    uri="http://localhost:19530",
)

index_params = client.prepare_index_params() # Prepare an empty IndexParams object, without having to specify any index parameters
index_params.add_index(
    field_name="category", # Name of the scalar field to be indexed
    index_type="BITMAP", # Type of index to be created
    index_name="category_bitmap_index" # Name of the index to be created
)

client.create_index(
    collection_name="my_collection", # Specify the collection name
    index_params=index_params
)
import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.common.IndexParam;
import io.milvus.v2.service.index.request.CreateIndexReq;
import java.util.Collections;

MilvusClientV2 client = new MilvusClientV2(ConnectConfig.builder()
        .uri("http://localhost:19530")
        .build());

client.createIndex(CreateIndexReq.builder()
        .collectionName("my_collection")
        .indexParams(Collections.singletonList(IndexParam.builder()
                .fieldName("category")
                .indexType(IndexParam.IndexType.BITMAP)
                .indexName("category_bitmap_index")
                .build()))
        .build());
import (
    "context"
    "log"

    "github.com/milvus-io/milvus/client/v3/index"
    "github.com/milvus-io/milvus/client/v3/milvusclient"
)

ctx := context.Background()

cli, err := milvusclient.New(ctx, &milvusclient.ClientConfig{
    Address: "http://localhost:19530",
})

if err != nil {
    log.Fatal("failed to connect to milvus server: ", err.Error())
}

_, err = cli.CreateIndex(ctx, milvusclient.NewCreateIndexOption("my_collection", "category", index.NewBitmapIndex()).WithIndexName("category_bitmap_index"))

if err != nil {
    log.Fatal("failed to create index: ", err.Error())
}
use milvus::v2::prelude::*;

let config = ConnectConfig::new().uri("http://localhost:19530");

let client = ClientV2::new(&config).await?;

client
    .create_index(
        CreateIndexRequest::builder()
            .collection_name("my_collection")
            .index_param(
                IndexParam::new()
                    .field_name("category")
                    .index_type(IndexType::Bitmap)
                    .index_name("category_bitmap_index"),
            )
            .build()?,
    )
    .await?;
#include <iostream>
#include "milvus/MilvusClientV2.h"

auto client = milvus::MilvusClientV2::Create();

auto status = client->Connect(milvus::ConnectParam("http://localhost:19530"));

if (!status.IsOk()) {
    std::cout << status.Message() << std::endl;
}

status = client->CreateIndex(milvus::CreateIndexRequest().WithCollectionName("my_collection")
        .AddIndex(milvus::IndexDesc("category", "category_bitmap_index", milvus::IndexType::BITMAP)));

if (!status.IsOk()) {
    std::cout << status.Message() << std::endl;
}
import { MilvusClient } from "@zilliz/milvus2-sdk-node";

const client = new MilvusClient({ address: "http://localhost:19530" });

await client.createIndex({
    collection_name: "my_collection",
    field_name: "category",
    index_type: "BITMAP",
    index_name: "category_bitmap_index",
});
using Milvus.Client.V2;
using Milvus.Client.V2.Requests.Index;
using Milvus.Client.V2.Types;

var config = new ConnectConfig
{
    Uri = "http://localhost:19530"
};
using var client = new MilvusClientV2(config);
await client.ConnectAsync();

// Prepare index building params
var indexParam = new IndexParam(
    fieldName: "category",
    indexType: IndexType.Bitmap,
    indexName: "category_bitmap_index");

await client.CreateIndexAsync(new CreateIndexReq
{
    CollectionName = "my_collection",
    Indexes = [indexParam]
});
export CLUSTER_ENDPOINT="http://localhost:19530"
export TOKEN="root:Milvus"

curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/indexes/create" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
--header "Request-Timeout: 10" \
-d '{
    "collectionName": "my_collection",
    "indexParams": [
        {
            "fieldName": "category",
            "indexName": "category_bitmap_index",
            "indexType": "BITMAP"
        }
    ]
}'

# {
#     "code": 0,
#     "data": {}
# }

В этом примере мы создаем битовый индекс для поля ` category ` коллекции ` my_collection `. Метод ` add_index() ` используется для указания имени поля, типа индекса и имени индекса.

После создания растрового индекса можно использовать параметр ` filter ` в операциях запроса для выполнения скалярной фильтрации на основе индексированного поля. Это позволяет эффективно сужать результаты поиска с помощью растрового индекса. Дополнительные сведения см. в разделе «Объяснение фильтрации».

Удаление индекса

Используйте метод ` drop_index() ` для удаления существующего индекса из коллекции.

  • В версии 2.6.3 и более ранних версиях перед удалением скалярного индекса необходимо освободить коллекцию.

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

client.drop_index(
    collection_name="my_collection",   # Name of the collection
    index_name="category_bitmap_index" # Name of the index to drop
)
import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.service.index.request.DropIndexReq;

MilvusClientV2 client = new MilvusClientV2(ConnectConfig.builder()
        .uri("http://localhost:19530")
        .build());

client.dropIndex(DropIndexReq.builder()
        .collectionName("my_collection")
        .indexName("category_bitmap_index")
        .build());
import (
    "context"
    "log"

    "github.com/milvus-io/milvus/client/v3/milvusclient"
)

ctx := context.Background()

cli, err := milvusclient.New(ctx, &milvusclient.ClientConfig{
    Address: "http://localhost:19530",
})

if err != nil {
    log.Fatal("failed to connect to milvus server: ", err.Error())
}

err = cli.DropIndex(ctx, milvusclient.NewDropIndexOption("my_collection", "category_bitmap_index"))

if err != nil {
    log.Fatal("failed to drop index: ", err.Error())
}
use milvus::v2::prelude::*;

let config = ConnectConfig::new().uri("http://localhost:19530");

let client = ClientV2::new(&config).await?;

client
    .drop_index(
        DropIndexRequest::builder()
            .collection_name("my_collection")
            .index_name("category_bitmap_index")
            .build()?,
    )
    .await?;
#include <iostream>
#include "milvus/MilvusClientV2.h"

auto client = milvus::MilvusClientV2::Create();

auto status = client->Connect(milvus::ConnectParam("http://localhost:19530"));

if (!status.IsOk()) {
    std::cout << status.Message() << std::endl;
}

status = client->DropIndex(milvus::DropIndexRequest()
        .WithCollectionName("my_collection")
        .WithIndexName("category_bitmap_index"));

if (!status.IsOk()) {
    std::cout << status.Message() << std::endl;
}
import { MilvusClient } from "@zilliz/milvus2-sdk-node";

const client = new MilvusClient({ address: "http://localhost:19530" });

await client.dropIndex({
    collection_name: "my_collection",
    index_name: "category_bitmap_index",
});
using Milvus.Client.V2.Requests.Index;

await client.DropIndexAsync(new DropIndexReq
{
    CollectionName = "my_collection", // Name of the collection
    IndexName = "category_bitmap_index" // Name of the index to drop
});
export CLUSTER_ENDPOINT="http://localhost:19530"
export TOKEN="root:Milvus"

curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/indexes/drop" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
--header "Request-Timeout: 10" \
-d '{
    "collectionName": "my_collection",
    "indexName": "category_bitmap_index"
}'

# {
#     "code": 0,
#     "data": {}
# }

Ограничения

  • Битовые индексы поддерживаются только для скалярных полей, не являющихся первичными ключами.

  • Тип данных поля должен быть одним из следующих:

    • BOOL, INT8, INT16, INT32, INT64, VARCHAR

    • ARRAY (элементы должны быть одним из следующих: BOOL, INT8, INT16, INT32, INT64, VARCHAR)

  • Растровые индексы не поддерживают следующие типы данных:

    • FLOAT, DOUBLE: Типы с плавающей запятой несовместимы с двоичной природой растровых индексов.

    • JSON: Типы данных JSON имеют сложную структуру, которую невозможно эффективно представить с помощью растровых индексов.

  • Битовые индексы не подходят для полей с высокой кардинальностью (т. е. полей с большим количеством различных значений).

    • Как правило, растровые индексы наиболее эффективны, когда кардинальность поля меньше 500.

    • Когда кардинальность превышает этот порог, преимущества растровых индексов в плане производительности снижаются, а накладные расходы на хранение становятся значительными.

    • Для полей с высокой кардинальностью рекомендуется рассмотреть возможность использования альтернативных методов индексирования, таких как инвертированные индексы, в зависимости от конкретного сценария использования и требований к запросам.

ПереведеноDeepL

Попробуйте Managed Milvus бесплатно

Zilliz Cloud работает без проблем, поддерживается Milvus и в 10 раз быстрее.

Начать
Обратная связь

Была ли эта страница полезной?