🚀 Попробуйте Zilliz Cloud, полностью управляемый Milvus, бесплатно — ощутите 10-кратное увеличение производительности! Попробовать сейчас>

milvus-logo
LFAI
Главная
  • Руководство пользователя
  • Home
  • Docs
  • Руководство пользователя

  • Схема и поля данных

  • Числовое поле

Числовое поле

Числовые поля используются для хранения невекторных числовых данных в Milvus. Эти поля обычно используются для описания дополнительной информации, связанной с векторными данными, такой как возраст, цена и т. д. Используя эти данные, вы можете лучше описать векторы и повысить эффективность фильтрации данных и условных запросов.

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

Поддерживаемые типы числовых полей

Milvus поддерживает различные типы числовых полей для удовлетворения различных потребностей в хранении данных и запросов.

Тип

Описание

BOOL

Булевский тип для хранения true или false, подходит для описания бинарных состояний.

INT8

8-битное целое число, подходит для хранения целочисленных данных небольшого диапазона.

INT16

16-битное целое число, для хранения целочисленных данных среднего диапазона.

INT32

32-битное целое число, идеально подходящее для хранения общих целочисленных данных, таких как количество продукции или идентификаторы пользователей.

INT64

64-битное целое число, подходящее для хранения данных большого диапазона, таких как временные метки или идентификаторы.

FLOAT

32-битное число с плавающей точкой - для данных, требующих общей точности, таких как номиналы или температура.

DOUBLE

64-битное число с плавающей запятой двойной точности - для данных высокой точности, таких как финансовая информация или научные расчеты.

Добавление числового поля

Чтобы использовать числовые поля в Milvus, определите соответствующие поля в схеме коллекции, установив для datatype поддерживаемый тип, например BOOL или INT8. Полный список поддерживаемых типов числовых полей см. в разделе Поддерживаемые типы числовых полей.

В следующем примере показано, как определить схему, включающую числовые поля age и price.

from pymilvus import MilvusClient, DataType

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

schema = client.create_schema(
    auto_id=False,
    enable_dynamic_fields=True,
)

schema.add_field(field_name="age", datatype=DataType.INT64)
schema.add_field(field_name="price", datatype=DataType.FLOAT)
schema.add_field(field_name="pk", datatype=DataType.INT64, is_primary=True)
schema.add_field(field_name="embedding", datatype=DataType.FLOAT_VECTOR, dim=3)

import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2;

import io.milvus.v2.common.DataType;
import io.milvus.v2.service.collection.request.AddFieldReq;
import io.milvus.v2.service.collection.request.CreateCollectionReq;


MilvusClientV2 client = new MilvusClientV2(ConnectConfig.builder()
        .uri("http://localhost:19530")
        .build());
        
CreateCollectionReq.CollectionSchema schema = client.createSchema();
schema.setEnableDynamicField(true);

schema.addField(AddFieldReq.builder()
        .fieldName("age")
        .dataType(DataType.Int64)
        .build());

schema.addField(AddFieldReq.builder()
        .fieldName("price")
        .dataType(DataType.Float)
        .build());

schema.addField(AddFieldReq.builder()
        .fieldName("pk")
        .dataType(DataType.Int64)
        .isPrimaryKey(true)
        .build());

schema.addField(AddFieldReq.builder()
        .fieldName("embedding")
        .dataType(DataType.FloatVector)
        .dimension(3)
        .build());

import { MilvusClient, DataType } from "@zilliz/milvus2-sdk-node";
const schema = [
  {
    name: "age",
    data_type: DataType.Int64,
  },
  {
    name: "price",
    data_type: DataType.Float,
  },
  {
    name: "pk",
    data_type: DataType.Int64,
    is_primary_key: true,
  },
  {
    name: "embedding",
    data_type: DataType.FloatVector,
    dim: 3,
  },
];


export int64Field='{
    "fieldName": "age",
    "dataType": "Int64"
}'

export floatField='{
    "fieldName": "price",
    "dataType": "Float"
}'

export pkField='{
    "fieldName": "pk",
    "dataType": "Int64",
    "isPrimary": true
}'

export vectorField='{
    "fieldName": "embedding",
    "dataType": "FloatVector",
    "elementTypeParams": {
        "dim": 3
    }
}'

export schema="{
    \"autoID\": false,
    \"fields\": [
        $int64Field,
        $floatField,
        $pkField,
        $vectorField
    ]
}"

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

Установка индексных параметров

Установка параметров индекса для числовых полей необязательна, но может значительно повысить эффективность поиска.

В следующем примере мы создаем AUTOINDEX для числового поля age, что позволяет Milvus автоматически создавать соответствующий индекс на основе типа данных. Дополнительные сведения см. в разделе АВТОИНДЕКС.

index_params = client.prepare_index_params()

index_params.add_index(
    field_name="age",
    index_type="AUTOINDEX",
    index_name="inverted_index"
)

import io.milvus.v2.common.IndexParam;
import java.util.*;

List<IndexParam> indexes = new ArrayList<>();
indexes.add(IndexParam.builder()
        .fieldName("age")
        .indexType(IndexParam.IndexType.AUTOINDEX)
        .build());


const indexParams = {
    index_name: 'inverted_index',
    field_name: 'age',
    index_type: IndexType.AUTOINDEX,
);

export indexParams='[
        {
            "fieldName": "age",
            "indexName": "inverted_index",
            "indexType": "AUTOINDEX"
        }
    ]'

Помимо AUTOINDEX, вы можете указать другие типы индексов для числовых полей. Поддерживаемые типы индексов см. в разделе Скалярные индексы.

Кроме того, перед созданием коллекции необходимо создать индекс для векторного поля. В этом примере мы используем AUTOINDEX, чтобы упростить настройку векторного индекса.

# Add vector index
index_params.add_index(
    field_name="embedding",
    index_type="AUTOINDEX",  # Use automatic indexing to simplify complex index settings
    metric_type="COSINE"  # Specify similarity metric type, options include L2, COSINE, or IP
)

indexes.add(IndexParam.builder()
        .fieldName("embedding")
        .indexType(IndexParam.IndexType.AUTOINDEX)
        .metricType(IndexParam.MetricType.COSINE)
        .build());

import { IndexType } from "@zilliz/milvus2-sdk-node";
const indexParams = [
  {
    field_name: "age",
    index_name: "inverted_index",
    index_type: IndexType.AUTOINDEX,
  },
  {
    field_name: "embedding",
    metric_type: "COSINE",
    index_type: IndexType.AUTOINDEX,
  },
];


export indexParams='[
        {
            "fieldName": "age",
            "indexName": "inverted_index",
            "indexType": "AUTOINDEX"
        },
        {
            "fieldName": "embedding",
            "metricType": "COSINE",
            "indexType": "AUTOINDEX"
        }
    ]'

Создание коллекции

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

# Create Collection
client.create_collection(
    collection_name="your_collection_name",
    schema=schema,
    index_params=index_params
)

CreateCollectionReq requestCreate = CreateCollectionReq.builder()
        .collectionName("my_scalar_collection")
        .collectionSchema(schema)
        .indexParams(indexes)
        .build();
client.createCollection(requestCreate);

client.create_collection({
    collection_name: "my_scalar_collection",
    schema: schema,
    index_params: indexParams
})

curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/collections/create" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
-d "{
    \"collectionName\": \"my_scalar_collection\",
    \"schema\": $schema,
    \"indexParams\": $indexParams
}"

Вставка данных

После создания коллекции вы можете вставить данные, включающие числовые поля.

data = [
    {"age": 25, "price": 99.99, "pk": 1, "embedding": [0.1, 0.2, 0.3]},
    {"age": 30, "price": 149.50, "pk": 2, "embedding": [0.4, 0.5, 0.6]},
    {"age": 35, "price": 199.99, "pk": 3, "embedding": [0.7, 0.8, 0.9]},
]

client.insert(
    collection_name="my_scalar_collection",
    data=data
)

import com.google.gson.Gson;
import com.google.gson.JsonObject;

import io.milvus.v2.service.vector.request.InsertReq;
import io.milvus.v2.service.vector.response.InsertResp;

List<JsonObject> rows = new ArrayList<>();
Gson gson = new Gson();
rows.add(gson.fromJson("{\"age\": 25, \"price\": 99.99, \"pk\": 1, \"embedding\": [0.1, 0.2, 0.3]}", JsonObject.class));
rows.add(gson.fromJson("{\"age\": 30, \"price\": 149.50, \"pk\": 2, \"embedding\": [0.4, 0.5, 0.6]}", JsonObject.class));
rows.add(gson.fromJson("{\"age\": 35, \"price\": 199.99, \"pk\": 3, \"embedding\": [0.7, 0.8, 0.9]}", JsonObject.class));

InsertResp insertR = client.insert(InsertReq.builder()
        .collectionName("my_scalar_collection")
        .data(rows)
        .build());

const data = [
  { age: 25, price: 99.99, pk: 1, embedding: [0.1, 0.2, 0.3] },
  { age: 30, price: 149.5, pk: 2, embedding: [0.4, 0.5, 0.6] },
  { age: 35, price: 199.99, pk: 3, embedding: [0.7, 0.8, 0.9] },
];

client.insert({
  collection_name: "my_scalar_collection",
  data: data,
});


curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/entities/insert" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
-d '{
    "data": [
        {"age": 25, "price": 99.99, "pk": 1, "embedding": [0.1, 0.2, 0.3]},
        {"age": 30, "price": 149.50, "pk": 2, "embedding": [0.4, 0.5, 0.6]},
        {"age": 35, "price": 199.99, "pk": 3, "embedding": [0.7, 0.8, 0.9]}       
    ],
    "collectionName": "my_scalar_collection"
}'

В этом примере мы вставляем данные, включающие age, price, pk (основное поле) и векторное представление (embedding). Чтобы убедиться, что вставляемые данные соответствуют полям, определенным в схеме, рекомендуется заранее проверить типы данных, чтобы избежать ошибок.

Если при определении схемы вы установите значение enable_dynamic_fields=True, Milvus позволит вам вставлять числовые поля, которые не были определены заранее. Однако имейте в виду, что это может увеличить сложность запросов и управления, что потенциально может повлиять на производительность. Дополнительную информацию см. в разделе Динамическое поле.

Поиск и запросы

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

Фильтр запросов

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

filter = "30 <= age <= 40"

res = client.query(
    collection_name="my_scalar_collection",
    filter=filter,
    output_fields=["age","price"]
)

print(res)

# Output
# data: ["{'age': 30, 'price': np.float32(149.5), 'pk': 2}", "{'age': 35, 'price': np.float32(199.99), 'pk': 3}"] 

import io.milvus.v2.service.vector.request.QueryReq;
import io.milvus.v2.service.vector.response.QueryResp;

String filter = "30 <= age <= 40";

QueryResp resp = client.query(QueryReq.builder()
        .collectionName("my_scalar_collection")
        .filter(filter)
        .outputFields(Arrays.asList("age", "price"))
        .build());
System.out.println(resp.getQueryResults());

// Output
//
// [QueryResp.QueryResult(entity={price=149.5, pk=2, age=30}), QueryResp.QueryResult(entity={price=199.99, pk=3, age=35})]

client.query({
    collection_name: 'my_scalar_collection',
    filter: '30 <= age <= 40',
    output_fields: ['age', 'price']
});

curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/entities/query" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
-d '{
    "collectionName": "my_scalar_collection",
    "filter": "30 <= age <= 40",
    "outputFields": ["age","price"]
}'

## {"code":0,"cost":0,"data":[{"age":30,"pk":2,"price":149.5},{"age":35,"pk":3,"price":199.99}]}

Это выражение запроса возвращает все совпадающие сущности и выводит их поля age и price. Дополнительные сведения о фильтрации запросов см. в разделе Фильтрация метаданных.

Векторный поиск с фильтрацией по числам

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

filter = "25 <= age <= 35"

res = client.search(
    collection_name="my_scalar_collection",
    data=[[0.3, -0.6, 0.1]],
    limit=5,
    search_params={"params": {"nprobe": 10}},
    output_fields=["age","price"],
    filter=filter
)

print(res)

# Output
# data: ["[{'id': 1, 'distance': -0.06000000238418579, 'entity': {'age': 25, 'price': 99.98999786376953}}, {'id': 2, 'distance': -0.12000000476837158, 'entity': {'age': 30, 'price': 149.5}}, {'id': 3, 'distance': -0.18000000715255737, 'entity': {'age': 35, 'price': 199.99000549316406}}]"]

import io.milvus.v2.service.vector.request.SearchReq;
import io.milvus.v2.service.vector.request.data.FloatVec;
import io.milvus.v2.service.vector.response.SearchResp;

String filter = "25 <= age <= 35";

SearchResp resp = client.search(SearchReq.builder()
        .collectionName("my_scalar_collection")
        .annsField("embedding")
        .data(Collections.singletonList(new FloatVec(new float[]{0.3f, -0.6f, 0.1f})))
        .topK(5)
        .outputFields(Arrays.asList("age", "price"))
        .filter(filter)
        .build());

System.out.println(resp.getSearchResults());

// Output
//
// [[SearchResp.SearchResult(entity={price=199.99, age=35}, score=-0.19054288, id=3), SearchResp.SearchResult(entity={price=149.5, age=30}, score=-0.20163085, id=2), SearchResp.SearchResult(entity={price=99.99, age=25}, score=-0.2364331, id=1)]]

client.search({
    collection_name: 'my_scalar_collection',
    data: [0.3, -0.6, 0.1],
    limit: 5,
    output_fields: ['age', 'price'],
    filter: '25 <= age <= 35'
});

curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/entities/search" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
-d '{
    "collectionName": "my_scalar_collection",
    "data": [
        [0.3, -0.6, 0.1]
    ],
    "annsField": "embedding",
    "limit": 5,
    "outputFields": ["age", "price"]
}'

## {"code":0,"cost":0,"data":[{"age":35,"distance":-0.19054288,"id":3,"price":199.99},{"age":30,"distance":-0.20163085,"id":2,"price":149.5},{"age":25,"distance":-0.2364331,"id":1,"price":99.99}]}

В этом примере мы сначала определяем вектор запроса и добавляем условие фильтра 25 <= age <= 35 во время поиска. Это гарантирует, что результаты поиска будут не только похожи на вектор запроса, но и будут соответствовать заданному возрастному диапазону. Дополнительные сведения см. в разделе Фильтрация метаданных.

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

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

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

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