Запрос

Помимо поиска с помощью ANN, Milvus также поддерживает фильтрацию метаданных с помощью запросов. На этой странице описано, как использовать Query, Get и QueryIterators для извлечения сущностей, фильтрации метаданных, сортировки результатов запросов и агрегирования скалярных значений.

Если вы добавите новые поля после создания коллекции, запросы, включающие эти поля, будут возвращать заданные значения по умолчанию или значение « NULL » для сущностей, для которых значения явно не заданы. Подробности см. в разделе «Изменение схемы коллекции».

Обзор

Коллекция может хранить различные типы скалярных полей. Вы можете настроить Milvus на фильтрацию сущностей по одному или нескольким скалярным полям. Milvus предлагает три типа запросов: Query, Get и QueryIterator. В таблице ниже приведено сравнение этих трех типов запросов.

Get

Query

QueryIterator

Применимые сценарии

Для поиска сущностей, имеющих указанные первичные ключи.

Для поиска всех или заданного количества сущностей, удовлетворяющих условиям настраиваемой фильтрации

Для поиска всех сущностей, соответствующих пользовательским условиям фильтрации в запросах с пагинацией.

Метод фильтрации

По первичным ключам

По выражениям фильтрации.

По выражениям фильтрации.

Обязательные параметры

  • Имя коллекции

  • Первичные ключи

  • Имя коллекции

  • Выражения фильтрации

  • Имя коллекции

  • Выражения фильтрации

  • Количество сущностей, возвращаемых за один запрос

Необязательные параметры

  • Имя раздела

  • Поля вывода

  • Имя раздела

  • Количество сущностей для возврата

  • Поля вывода

  • Имя раздела

  • Общее количество сущностей для возврата

  • Поля вывода

Возвращает

Возвращает сущности, содержащие указанные первичные ключи в указанной коллекции или разделах.

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

Возвращает все сущности, соответствующие пользовательским условиям фильтрации в указанной коллекции или разделах, посредством запросов с пагинацией.

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

Использование метода Get

Если вам нужно найти сущности по их первичным ключам, можно использовать метод Get. В приведенных ниже примерах кода предполагается, что в вашей коллекции имеются три поля с именами id, vector и color.

[
        {"id": 0, "vector": [0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592], "color": "pink_8682"},
        {"id": 1, "vector": [0.19886812562848388, 0.06023560599112088, 0.6976963061752597, 0.2614474506242501, 0.838729485096104], "color": "red_7025"},
        {"id": 2, "vector": [0.43742130801983836, -0.5597502546264526, 0.6457887650909682, 0.7894058910881185, 0.20785793220625592], "color": "orange_6781"},
        {"id": 3, "vector": [0.3172005263489739, 0.9719044792798428, -0.36981146090600725, -0.4860894583077995, 0.95791889146345], "color": "pink_9298"},
        {"id": 4, "vector": [0.4452349528804562, -0.8757026943054742, 0.8220779437047674, 0.46406290649483184, 0.30337481143159106], "color": "red_4794"},
        {"id": 5, "vector": [0.985825131989184, -0.8144651566660419, 0.6299267002202009, 0.1206906911183383, -0.1446277761879955], "color": "yellow_4222"},
        {"id": 6, "vector": [0.8371977790571115, -0.015764369584852833, -0.31062937026679327, -0.562666951622192, -0.8984947637863987], "color": "red_9392"},
        {"id": 7, "vector": [-0.33445148015177995, -0.2567135004164067, 0.8987539745369246, 0.9402995886420709, 0.5378064918413052], "color": "grey_8510"},
        {"id": 8, "vector": [0.39524717779832685, 0.4000257286739164, -0.5890507376891594, -0.8650502298996872, -0.6140360785406336], "color": "white_9381"},
        {"id": 9, "vector": [0.5718280481994695, 0.24070317428066512, -0.3737913482606834, -0.06726932177492717, -0.6980531615588608], "color": "purple_4976"},
]

Получить сущности по их ID можно следующим образом.

from pymilvus import MilvusClient

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

res = client.get(
    collection_name="my_collection",
    ids=[0, 1, 2],
    output_fields=["vector", "color"]
)

print(res)
import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.service.vector.request.GetReq
import io.milvus.v2.service.vector.request.GetResp
import io.milvus.v2.service.vector.response.QueryResp;
import java.util.*;

MilvusClientV2 client = new MilvusClientV2(ConnectConfig.builder()
        .uri("http://localhost:19530")
        .token("root:Milvus")
        .build());
        
GetReq getReq = GetReq.builder()
        .collectionName("my_collection")
        .ids(Arrays.asList(0, 1, 2))
        .outputFields(Arrays.asList("vector", "color"))
        .build();

GetResp getResp = client.get(getReq);

List<QueryResp.QueryResult> results = getResp.getGetResults();
for (QueryResp.QueryResult result : results) {
    System.out.println(result.getEntity());
}

// Output
// {color=pink_8682, vector=[0.35803765, -0.6023496, 0.18414013, -0.26286206, 0.90294385], id=0}
// {color=red_7025, vector=[0.19886813, 0.060235605, 0.6976963, 0.26144746, 0.8387295], id=1}
// {color=orange_6781, vector=[0.43742132, -0.55975026, 0.6457888, 0.7894059, 0.20785794], id=2}
import (
    "context"
    "fmt"

    "github.com/milvus-io/milvus/client/v2/column"
    "github.com/milvus-io/milvus/client/v2/entity"
    "github.com/milvus-io/milvus/client/v2/milvusclient"
)

ctx, cancel := context.WithCancel(context.Background())
defer cancel()

milvusAddr := "localhost:19530"
client, err := milvusclient.New(ctx, &milvusclient.ClientConfig{
    Address: milvusAddr,
})
if err != nil {
    fmt.Println(err.Error())
    // handle error
}
defer client.Close(ctx)

resultSet, err := client.Get(ctx, milvusclient.NewQueryOption("my_collection").
    WithConsistencyLevel(entity.ClStrong).
    WithIDs(column.NewColumnInt64("id", []int64{0, 1, 2})).
    WithOutputFields("vector", "color"))
if err != nil {
    fmt.Println(err.Error())
    // handle error
}

fmt.Println("id: ", resultSet.GetColumn("id").FieldData().GetScalars())
fmt.Println("vector: ", resultSet.GetColumn("vector").FieldData().GetVectors())
fmt.Println("color: ", resultSet.GetColumn("color").FieldData().GetScalars())
import { MilvusClient, DataType } from "@zilliz/milvus2-sdk-node";

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

const res = client.get({
    collection_name="my_collection",
    ids=[0,1,2],
    output_fields=["vector", "color"]
})
export CLUSTER_ENDPOINT="http://localhost:19530"
export TOKEN="root:Milvus"

curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/entities/get" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
--header "Request-Timeout: 10" \
-d '{
    "collectionName": "my_collection",
    "id": [0, 1, 2],
    "outputFields": ["vector", "color"]
}'

# {"code":0,"cost":0,"data":[{"color":"pink_8682","id":0,"vector":[0.35803765,-0.6023496,0.18414013,-0.26286206,0.90294385]},{"color":"red_7025","id":1,"vector":[0.19886813,0.060235605,0.6976963,0.26144746,0.8387295]},{"color":"orange_6781","id":2,"vector":[0.43742132,-0.55975026,0.6457888,0.7894059,0.20785794]}]}
#include "milvus/MilvusClientV2.h"
#include <iostream>

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

milvus::ConnectParam connect_param{"http://localhost:19530", "root:Milvus"};
auto status = client->Connect(connect_param);
if (!status.IsOk()) {
    std::cout << status.Message() << std::endl;
}

auto request = milvus::GetRequest()
                   .WithCollectionName("my_collection")
                   .WithIDs({0, 1, 2})
                   .AddOutputField("vector")
                   .AddOutputField("color");

milvus::GetResponse response;
status = client->Get(request, response);
if (!status.IsOk()) {
    std::cout << status.Message() << std::endl;
}

Использование запроса

Базовый запрос

Если вам нужно найти сущности по пользовательским условиям фильтрации, используйте метод «Query ». В приведённых ниже примерах кода предполагается, что в коллекции имеются три поля с именами id, vector и color, и возвращается указанное количество сущностей, содержащих значение « color », начинающееся с « red ».

from pymilvus import MilvusClient

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

res = client.query(
    collection_name="my_collection",
    filter="color like \"red%\"",
    output_fields=["vector", "color"],
    limit=3
)
import io.milvus.v2.service.vector.request.QueryReq
import io.milvus.v2.service.vector.request.QueryResp

QueryReq queryReq = QueryReq.builder()
        .collectionName("my_collection")
        .filter("color like \"red%\"")
        .outputFields(Arrays.asList("vector", "color"))
        .limit(3)
        .build();

QueryResp queryResp = client.query(queryReq);

List<QueryResp.QueryResult> results = queryResp.getQueryResults();
for (QueryResp.QueryResult result : results) {
    System.out.println(result.getEntity());
}

// Output
// {color=red_7025, vector=[0.19886813, 0.060235605, 0.6976963, 0.26144746, 0.8387295], id=1}
// {color=red_4794, vector=[0.44523495, -0.8757027, 0.82207793, 0.4640629, 0.3033748], id=4}
// {color=red_9392, vector=[0.8371978, -0.015764369, -0.31062937, -0.56266695, -0.8984948], id=6}
resultSet, err := client.Query(ctx, milvusclient.NewQueryOption("my_collection").
    WithFilter("color like \"red%\"").
    WithOutputFields("vector", "color"))
if err != nil {
    fmt.Println(err.Error())
    // handle error
}

fmt.Println("id: ", resultSet.GetColumn("id").FieldData().GetScalars())
fmt.Println("vector: ", resultSet.GetColumn("vector").FieldData().GetVectors())
fmt.Println("color: ", resultSet.GetColumn("color").FieldData().GetScalars())

import { MilvusClient, DataType } from "@zilliz/milvus2-sdk-node";

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

const res = client.query({
    collection_name="my_collection",
    filter='color like "red%"',
    output_fields=["vector", "color"],
    limit(3)
})
export CLUSTER_ENDPOINT="http://localhost:19530"
export TOKEN="root:Milvus"

curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/entities/query" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
--header "Request-Timeout: 10" \
-d '{
    "collectionName": "my_collection",
    "filter": "color like \"red%\"",
    "limit": 3,
    "outputFields": ["vector", "color"]
}'
#{"code":0,"cost":0,"data":[{"color":"red_7025","id":1,"vector":[0.19886813,0.060235605,0.6976963,0.26144746,0.8387295]},{"color":"red_4794","id":4,"vector":[0.44523495,-0.8757027,0.82207793,0.4640629,0.3033748]},{"color":"red_9392","id":6,"vector":[0.8371978,-0.015764369,-0.31062937,-0.56266695,-0.8984948]}]}
#include "milvus/MilvusClientV2.h"
#include <iostream>

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

milvus::ConnectParam connect_param{"http://localhost:19530", "root:Milvus"};
auto status = client->Connect(connect_param);
if (!status.IsOk()) {
    std::cout << status.Message() << std::endl;
}

auto request = milvus::QueryRequest()
                   .WithCollectionName("my_collection")
                   .WithFilter("color like \"red%\"")
                   .WithLimit(3)
                   .AddOutputField("vector")
                   .AddOutputField("color");

milvus::QueryResponse response;
status = client->Query(request, response);
if (!status.IsOk()) {
    std::cout << status.Message() << std::endl;
}

Сортировка результатов запросаCompatible with Milvus 3.0.x

По умолчанию функция Query возвращает результаты в произвольном порядке. Используйте параметр order_by для сортировки результатов по одному или нескольким скалярным полям. При использовании параметра order_by обратите внимание на следующее:

  • order_by должен использоваться вместе с limit.

  • Поддерживаемые типы полей: INT8, INT16, INT32, INT64, FLOAT, DOUBLE и VARCHAR. Сортировка по векторным полям, полям типа JSON или ARRAY не поддерживается.

  • При сортировке по полю, допускающему значение NULL, значения NULL помещаются в конец списка при восходящем порядке (NULLS LAST) и в начало при нисходящем порядке (NULLS FIRST).

Базовая сортировка

Передайте список строк в формате "field_name:direction" в параметр order_by, где direction может принимать значения asc (по возрастанию) или desc (по убыванию). Обратите внимание, что asc и desc чувствительны к регистру.

from pymilvus import MilvusClient

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

# Sort results by id in ascending order
res = client.query(
    collection_name="my_collection",
    filter="color like \"red%\"",
    output_fields=["vector", "color"],
    limit=3,
    order_by=["id:asc"],
)
// java
// go
// nodejs
# restful
#include "milvus/MilvusClientV2.h"
#include <iostream>

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

milvus::ConnectParam connect_param{"http://localhost:19530", "root:Milvus"};
auto status = client->Connect(connect_param);
if (!status.IsOk()) {
    std::cout << status.Message() << std::endl;
}

// Sort results by id in ascending order
auto request = milvus::QueryRequest()
                   .WithCollectionName("my_collection")
                   .WithFilter("color like \"red%\"")
                   .WithLimit(3)
                   .WithOrderBy("id:asc")
                   .AddOutputField("vector")
                   .AddOutputField("color");

milvus::QueryResponse response;
status = client->Query(request, response);
if (!status.IsOk()) {
    std::cout << status.Message() << std::endl;
}

Сортировка по нескольким полям

Вы можете сортировать по нескольким полям одновременно. Результаты сначала упорядочиваются по первому полю в списке. Если две строки имеют одинаковое значение в этом поле, их порядок определяется вторым полем и так далее.

# Sort by rating descending, then by price ascending for ties
res = client.query(
    collection_name="my_collection",
    filter="",
    output_fields=["color", "rating", "price"],
    limit=10,
    order_by=["rating:desc", "price:asc"],
)
// java
// go
// nodejs
# restful
#include "milvus/MilvusClientV2.h"
#include <iostream>

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

milvus::ConnectParam connect_param{"http://localhost:19530", "root:Milvus"};
auto status = client->Connect(connect_param);
if (!status.IsOk()) {
    std::cout << status.Message() << std::endl;
}

// Sort by rating descending, then by price ascending for ties
auto request = milvus::QueryRequest()
                   .WithCollectionName("my_collection")
                   .WithFilter("")
                   .WithLimit(10)
                   .WithOrderBy("rating:desc")
                   .WithOrderBy("price:asc")
                   .AddOutputField("color")
                   .AddOutputField("rating")
                   .AddOutputField("price");

milvus::QueryResponse response;
status = client->Query(request, response);
if (!status.IsOk()) {
    std::cout << status.Message() << std::endl;
}

Пагинация с сортировкой

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

# Page 1
page1 = client.query(
    collection_name="my_collection",
    filter="color like \"red%\"",
    output_fields=["color", "price"],
    limit=5,
    offset=0,
    order_by=["price:asc"],
)

# Page 2
page2 = client.query(
    collection_name="my_collection",
    filter="color like \"red%\"",
    output_fields=["color", "price"],
    limit=5,
    offset=5,
    order_by=["price:asc"],
)
// java
// go
// nodejs
# restful
#include "milvus/MilvusClientV2.h"
#include <iostream>

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

milvus::ConnectParam connect_param{"http://localhost:19530", "root:Milvus"};
auto status = client->Connect(connect_param);
if (!status.IsOk()) {
    std::cout << status.Message() << std::endl;
}

// Page 1
auto request1 = milvus::QueryRequest()
                    .WithCollectionName("my_collection")
                    .WithFilter("color like \"red%\"")
                    .WithLimit(5)
                    .WithOffset(0)
                    .WithOrderBy("price:asc")
                    .AddOutputField("color")
                    .AddOutputField("price");

milvus::QueryResponse response1;
status = client->Query(request1, response1);
if (!status.IsOk()) {
    std::cout << status.Message() << std::endl;
}

// Page 2
auto request2 = milvus::QueryRequest()
                    .WithCollectionName("my_collection")
                    .WithFilter("color like \"red%\"")
                    .WithLimit(5)
                    .WithOffset(5)
                    .WithOrderBy("price:asc")
                    .AddOutputField("color")
                    .AddOutputField("price");

milvus::QueryResponse response2;
status = client->Query(request2, response2);
if (!status.IsOk()) {
    std::cout << status.Message() << std::endl;
}

Агрегирование результатов запросаCompatible with Milvus 3.0.x

Вы можете группировать результаты запроса по одному или нескольким скалярным полям и вычислять агрегаты по каждой группе. Поддерживаются следующие операторы агрегации: count, min, max, sum и avg.

При использовании оператора group_by_fields следует учитывать следующее:

  • Поддерживаемые типы полей для group_by_fields: INT8, INT16, INT32, INT64, VARCHAR и TIMESTAMPTZ. Группировка по полям FLOAT, DOUBLE, vector, JSON или ARRAY приводит к ошибке.

  • sum а также avg — исключительно числовые. Их можно применять к числовым полям, включая FLOAT и DOUBLE, но применение их к полю VARCHAR возвращает ошибку.

Чтобы включить агрегирование, передайте group_by_fields в query() и добавьте выражения агрегирования (count(*), count(<field>), min(<field>), max(<field>), sum(<field>), avg(<field>)) в output_fields.

В следующем примере сущности группируются по полю « color » и возвращается количество сущностей в каждой цветовой группе:

from pymilvus import MilvusClient

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

res = client.query(
    collection_name="my_collection",
    filter="",
    group_by_fields=["color"],
    output_fields=["color", "count(*)"],
)

# [{'color': 'red',    'count(*)': 10},
#  {'color': 'orange', 'count(*)': 10},
#  {'color': 'yellow', 'count(*)': 10},
#  {'color': 'green',  'count(*)': 10},
#  {'color': 'blue',   'count(*)': 10}]
// java
// go
// nodejs
# restful
#include "milvus/MilvusClientV2.h"
#include <iostream>

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

milvus::ConnectParam connect_param{"http://localhost:19530", "root:Milvus"};
auto status = client->Connect(connect_param);
if (!status.IsOk()) {
    std::cout << status.Message() << std::endl;
}

auto request = milvus::QueryRequest()
                   .WithCollectionName("my_collection")
                   .WithFilter("")
                   .WithGroupByFields({"color"})
                   .AddOutputField("color")
                   .AddOutputField("count(*)");

milvus::QueryResponse response;
status = client->Query(request, response);
if (!status.IsOk()) {
    std::cout << status.Message() << std::endl;
}

Вы можете запросить несколько выражений агрегации в одном вызове. В следующем примере объекты группируются по полю « color », и для каждой группы возвращаются количество объектов, средняя цена и максимальный рейтинг:

res = client.query(
    collection_name="my_collection",
    filter="",
    group_by_fields=["color"],
    output_fields=["color", "count(*)", "avg(price)", "max(rating)"],
)

# [{'color': 'red',    'count(*)': 10, 'avg(price)': 65.22, 'max(rating)': 5},
#  {'color': 'orange', 'count(*)': 10, 'avg(price)': 48.67, 'max(rating)': 5},
#  {'color': 'yellow', 'count(*)': 10, 'avg(price)': 64.15, 'max(rating)': 3},
#  {'color': 'green',  'count(*)': 10, 'avg(price)': 58.28, 'max(rating)': 5},
#  {'color': 'blue',   'count(*)': 10, 'avg(price)': 50.20, 'max(rating)': 5}]
// java
// go
// nodejs
# restful
#include "milvus/MilvusClientV2.h"
#include <iostream>

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

milvus::ConnectParam connect_param{"http://localhost:19530", "root:Milvus"};
auto status = client->Connect(connect_param);
if (!status.IsOk()) {
    std::cout << status.Message() << std::endl;
}

auto request = milvus::QueryRequest()
                   .WithCollectionName("my_collection")
                   .WithFilter("")
                   .WithGroupByFields({"color"})
                   .AddOutputField("color")
                   .AddOutputField("count(*)")
                   .AddOutputField("avg(price)")
                   .AddOutputField("max(rating)");

milvus::QueryResponse response;
status = client->Query(request, response);
if (!status.IsOk()) {
    std::cout << status.Message() << std::endl;
}

Передайте несколько полей в ` group_by_fields `, чтобы вычислить составные группы. В следующем примере выполняется группировка по ` (color, rating) `, и вычисляется диапазон цен в каждой группе:

res = client.query(
    collection_name="my_collection",
    filter="",
    group_by_fields=["color", "rating"],
    output_fields=["color", "rating", "min(price)", "max(price)"],
)

# [{'color': 'red',    'rating': 5, 'min(price)': 34.51, 'max(price)': 70.90},
#  {'color': 'orange', 'rating': 2, 'min(price)': 12.39, 'max(price)': 81.99},
#  {'color': 'yellow', 'rating': 2, 'min(price)': 22.62, 'max(price)': 88.24},
#  {'color': 'green',  'rating': 1, 'min(price)': 18.35, 'max(price)': 59.53},
#  {'color': 'blue',   'rating': 4, 'min(price)': 21.23, 'max(price)': 82.45},
#  ...]
// java
// go
// nodejs
# restful
#include "milvus/MilvusClientV2.h"
#include <iostream>

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

milvus::ConnectParam connect_param{"http://localhost:19530", "root:Milvus"};
auto status = client->Connect(connect_param);
if (!status.IsOk()) {
    std::cout << status.Message() << std::endl;
}

auto request = milvus::QueryRequest()
                   .WithCollectionName("my_collection")
                   .WithFilter("")
                   .WithGroupByFields({"color", "rating"})
                   .AddOutputField("color")
                   .AddOutputField("rating")
                   .AddOutputField("min(price)")
                   .AddOutputField("max(price)");

milvus::QueryResponse response;
status = client->Query(request, response);
if (!status.IsOk()) {
    std::cout << status.Message() << std::endl;
}

Вы также можете комбинировать group_by_fields с limit, чтобы ограничить количество возвращаемых групп. Это полезно, когда поле имеет высокую кардинальность, а вам нужна только выборка групп:

res = client.query(
    collection_name="my_collection",
    filter="",
    group_by_fields=["color"],
    output_fields=["color", "avg(price)", "count(*)"],
    limit=5,
)

# [{'color': 'red',    'avg(price)': 65.22, 'count(*)': 10},
#  {'color': 'orange', 'avg(price)': 48.67, 'count(*)': 10},
#  {'color': 'yellow', 'avg(price)': 64.15, 'count(*)': 10},
#  {'color': 'green',  'avg(price)': 58.28, 'count(*)': 10},
#  {'color': 'blue',   'avg(price)': 50.20, 'count(*)': 10}]
// java
// go
// nodejs
# restful
#include "milvus/MilvusClientV2.h"
#include <iostream>

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

milvus::ConnectParam connect_param{"http://localhost:19530", "root:Milvus"};
auto status = client->Connect(connect_param);
if (!status.IsOk()) {
    std::cout << status.Message() << std::endl;
}

auto request = milvus::QueryRequest()
                   .WithCollectionName("my_collection")
                   .WithFilter("")
                   .WithGroupByFields({"color"})
                   .AddOutputField("color")
                   .AddOutputField("avg(price)")
                   .AddOutputField("count(*)")
                   .WithLimit(5);

milvus::QueryResponse response;
status = client->Query(request, response);
if (!status.IsOk()) {
    std::cout << status.Message() << std::endl;
}

Используйте QueryIterator

Если вам нужно найти сущности по пользовательским условиям фильтрации с помощью запросов с пагинацией, создайте объект QueryIterator и используйте его метод next(), чтобы пройти по всем сущностям и найти те, которые соответствуют условиям фильтрации. В приведенных ниже примерах кода предполагается, что имеются три поля с именами id, vector и color, и возвращаются все сущности, содержащие значение color, начинающееся с red.

iterator = client.query_iterator(
    "my_collection",
    batch_size=10,
    filter="color like \"red%\"",
    output_fields=["color"]
)

results = []

while True:
    result = iterator.next()
    if not result:
        iterator.close()
        break

    print(result)
    results += result
import io.milvus.orm.iterator.QueryIterator;
import io.milvus.response.QueryResultsWrapper;
import io.milvus.v2.common.ConsistencyLevel;
import io.milvus.v2.service.vector.request.QueryIteratorReq;

QueryIteratorReq req = QueryIteratorReq.builder()
        .collectionName("my_collection")
        .expr("color like \"red%\"")
        .batchSize(10L)
        .outputFields(Collections.singletonList("color"))
        .build();
QueryIterator queryIterator = client.queryIterator(req);

while (true) {
    List<QueryResultsWrapper.RowRecord> res = queryIterator.next();
    if (res.isEmpty()) {
        queryIterator.close();
        break;
    }

    for (QueryResultsWrapper.RowRecord record : res) {
        System.out.println(record);
    }
}

// Output
// [color:red_7025, id:1]
// [color:red_4794, id:4]
// [color:red_9392, id:6]
// go
import { MilvusClient, DataType } from "@zilliz/milvus2-sdk-node";

const iterator = await milvusClient.queryIterator({
  collection_name: 'my_collection',
  batchSize: 10,
  expr: 'color like "red%"',
  output_fields: ['color'],
});

const results = [];
for await (const value of iterator) {
  results.push(...value);
  page += 1;
}
# Not available
// C++ QueryIterator is not supported in the current SDK.

Запросы в разделах

Вы также можете выполнять запросы в пределах одного или нескольких разделах, указав имена разделов в запросе Get, Query или QueryIterator. В приведенных ниже примерах кода предполагается, что в коллекции имеется раздел с именем PartitionA.

res = client.get(
    collection_name="my_collection",
    partitionNames=["partitionA"],
    ids=[10, 11, 12],
    output_fields=["vector", "color"]
)

res = client.query(
    collection_name="my_collection",
    partitionNames=["partitionA"],
    filter="color like \"red%\"",
    output_fields=["vector", "color"],
    limit=3
)

# Use QueryIterator
iterator = client.query_iterator(
    "my_collection",
    partition_names=["partitionA"],
    batch_size=10,
    filter="color like \"red%\"",
    output_fields=["color"]
)

results = []
while True:
    result = iterator.next()
    if not result:
        iterator.close()
        break

    print(result)
    results += result

GetReq getReq = GetReq.builder()
        .collectionName("my_collection")
        .partitionName("partitionA")
        .ids(Arrays.asList(10, 11, 12))
        .outputFields(Collections.singletonList("color"))
        .build();

GetResp getResp = client.get(getReq);

QueryReq queryReq = QueryReq.builder()
        .collectionName("my_collection")
        .partitionNames(Collections.singletonList("partitionA"))
        .filter("color like \"red%\"")
        .outputFields(Collections.singletonList("color"))
        .limit(3)
        .build();

QueryResp getResp = client.query(queryReq);

QueryIteratorReq req = QueryIteratorReq.builder()
        .collectionName("my_collection")
        .partitionNames(Collections.singletonList("partitionA"))
        .expr("color like \"red%\"")
        .batchSize(50L)
        .outputFields(Collections.singletonList("color"))
        .consistencyLevel(ConsistencyLevel.BOUNDED)
        .build();
QueryIterator queryIterator = client.queryIterator(req);
resultSet, err := client.Get(ctx, milvusclient.NewQueryOption("my_collection").
    WithPartitions("partitionA").
    WithIDs(column.NewColumnInt64("id", []int64{10, 11, 12})).
    WithOutputFields("vector", "color"))
if err != nil {
    fmt.Println(err.Error())
    // handle error
}

fmt.Println("id: ", resultSet.GetColumn("id").FieldData().GetScalars())
fmt.Println("vector: ", resultSet.GetColumn("vector").FieldData().GetVectors())
fmt.Println("color: ", resultSet.GetColumn("color").FieldData().GetScalars())

resultSet, err := client.Query(ctx, milvusclient.NewQueryOption("my_collection").
    WithPartitions("partitionA").
    WithFilter("color like \"red%\"").
    WithOutputFields("vector", "color"))
if err != nil {
    fmt.Println(err.Error())
    // handle error
}

fmt.Println("id: ", resultSet.GetColumn("id").FieldData().GetScalars())
fmt.Println("vector: ", resultSet.GetColumn("vector").FieldData().GetVectors())
fmt.Println("color: ", resultSet.GetColumn("color").FieldData().GetScalars())
// Use get
var res = client.get({
    collection_name="my_collection",
    partition_names=["partitionA"],
    ids=[10,11,12],
    output_fields=["vector", "color"]
})

// Use query
res = client.query({
    collection_name="my_collection",
    partition_names=["partitionA"],
    filter="color like \"red%\"",
    output_fields=["vector", "color"],
    limit(3)
})

// Use queryiterator
const iterator = await milvusClient.queryIterator({
  collection_name: 'my_collection',
  partition_names: ['partitionA'],
  batchSize: 10,
  expr: 'color like "red%"',
  output_fields: ['vector', 'color'],
});

const results = [];
for await (const value of iterator) {
  results.push(...value);
  page += 1;
}
export CLUSTER_ENDPOINT="http://localhost:19530"
export TOKEN="root:Milvus"

# Use get
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/entities/get" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
--header "Request-Timeout: 10" \
-d '{
    "collectionName": "my_collection",
    "partitionNames": ["partitionA"],
    "id": [10, 11, 12],
    "outputFields": ["vector", "color"]
}'

# Use query
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/entities/get" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
--header "Request-Timeout: 10" \
-d '{
    "collectionName": "my_collection",
    "partitionNames": ["partitionA"],
    "filter": "color like \"red%\"",
    "limit": 3,
    "outputFields": ["vector", "color"],
    "id": [0, 1, 2]
}'
#include "milvus/MilvusClientV2.h"
#include <iostream>

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

milvus::ConnectParam connect_param{"http://localhost:19530", "root:Milvus"};
auto status = client->Connect(connect_param);
if (!status.IsOk()) {
    std::cout << status.Message() << std::endl;
}

// Get entities from a partition
auto getRequest = milvus::GetRequest()
                      .WithCollectionName("my_collection")
                      .WithPartitionNames({"partitionA"})
                      .WithIDs({10, 11, 12})
                      .AddOutputField("vector")
                      .AddOutputField("color");

milvus::GetResponse getResponse;
status = client->Get(getRequest, getResponse);
if (!status.IsOk()) {
    std::cout << status.Message() << std::endl;
}

// Query a partition
auto queryRequest = milvus::QueryRequest()
                        .WithCollectionName("my_collection")
                        .WithPartitionNames({"partitionA"})
                        .WithFilter("color like \"red%\"")
                        .WithLimit(3)
                        .AddOutputField("vector")
                        .AddOutputField("color");

milvus::QueryResponse queryResponse;
status = client->Query(queryRequest, queryResponse);
if (!status.IsOk()) {
    std::cout << status.Message() << std::endl;
}

Случайная выборка с помощью запроса

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

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

# Sample 1% of the entire collection
res = client.query(
    collection_name="my_collection",
    filter="RANDOM_SAMPLE(0.01)",
    output_fields=["vector", "color"]
)

print(f"Sampled {len(res)} entities from collection")

# Combine with other filters - first filter, then sample
res = client.query(
    collection_name="my_collection", 
    filter="color like \"red%\" AND RANDOM_SAMPLE(0.005)",
    output_fields=["vector", "color"],
    limit=10
)

print(f"Found {len(res)} red items in sample")
import io.milvus.v2.service.vector.request.GetReq
import io.milvus.v2.service.vector.request.GetResp
import io.milvus.v2.service.vector.request.QueryReq
import io.milvus.v2.service.vector.request.QueryResp
import java.util.*;

QueryReq queryReq = QueryReq.builder()
        .collectionName("my_collection")
        .filter("RANDOM_SAMPLE(0.01)")
        .outputFields(Arrays.asList("vector", "color"))
        .build();

QueryResp getResp = client.query(queryReq);
for (QueryResp.QueryResult result : getResp.getQueryResults()) {
    System.out.println(result.getEntity());
}

queryReq = QueryReq.builder()
        .collectionName("my_collection")
        .filter("color like \"red%\" AND RANDOM_SAMPLE(0.005)")
        .outputFields(Arrays.asList("vector", "color"))
        .limit(10)
        .build();

getResp = client.query(queryReq);
for (QueryResp.QueryResult result : getResp.getQueryResults()) {
    System.out.println(result.getEntity());
}
import (
    "context"
    "fmt"

    "github.com/milvus-io/milvus/client/v2/column"
    "github.com/milvus-io/milvus/client/v2/entity"
    "github.com/milvus-io/milvus/client/v2/milvusclient"
)

resultSet, err := client.Query(ctx, milvusclient.NewQueryOption("my_collection").
    WithFilter("RANDOM_SAMPLE(0.01)").
    WithOutputFields("vector", "color"))
if err != nil {
    return err
}

resultSet, err = client.Query(ctx, milvusclient.NewQueryOption("my_collection").
    WithFilter("color like \"red%\" AND RANDOM_SAMPLE(0.005)").
    WithLimit(10).
    WithOutputFields("vector", "color"))
if err != nil {
    return err
}
// node
# restful
#include "milvus/MilvusClientV2.h"
#include <iostream>

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

milvus::ConnectParam connect_param{"http://localhost:19530", "root:Milvus"};
auto status = client->Connect(connect_param);
if (!status.IsOk()) {
    std::cout << status.Message() << std::endl;
}

// Sample 1% of the entire collection
auto request1 = milvus::QueryRequest()
                    .WithCollectionName("my_collection")
                    .WithFilter("RANDOM_SAMPLE(0.01)")
                    .AddOutputField("vector")
                    .AddOutputField("color");

milvus::QueryResponse response1;
status = client->Query(request1, response1);
if (!status.IsOk()) {
    std::cout << status.Message() << std::endl;
}

// Combine with other filters - first filter, then sample
auto request2 = milvus::QueryRequest()
                    .WithCollectionName("my_collection")
                    .WithFilter("color like \"red%\" AND RANDOM_SAMPLE(0.005)")
                    .WithLimit(10)
                    .AddOutputField("vector")
                    .AddOutputField("color");

milvus::QueryResponse response2;
status = client->Query(request2, response2);
if (!status.IsOk()) {
    std::cout << status.Message() << std::endl;
}

Временная настройка часового пояса для запроса

Если в вашей коллекции есть поле ` TIMESTAMPTZ `, вы можете временно переопределить часовой пояс по умолчанию базы данных или коллекции для одной операции, указав параметр ` timezone ` в вызове запроса. Это определяет, как значения ` TIMESTAMPTZ ` будут отображаться и сравниваться во время операции.

Значение timezone должно быть допустимым идентификатором часового пояса IANA (например, Asia/Shanghai, America/Chicago или UTC). Подробные сведения об использовании поля TIMESTAMPTZ см. в разделе «Поле TIMESTAMPTZ».

В приведенном ниже примере показано, как временно установить часовой пояс для операции запроса:

# Query data and display the tsz field converted to "America/Havana"
results = client.query(
    "my_collection",
    filter="id <= 10",
    output_fields=["id", "tsz", "vec"],
    limit=2,
    timezone="America/Havana",
)
import io.milvus.v2.service.vector.request.QueryReq
import io.milvus.v2.service.vector.request.QueryResp
import java.util.*;

// Query data and display the tsz field converted to "America/Havana"
QueryReq queryReq = QueryReq.builder()
        .collectionName("my_collection")
        .filter("id <= 10")
        .outputFields(Arrays.asList("id", "tsz", "vec"))
        .limit(2)
        .timeZone("America/Havana")
        .build();

QueryResp queryResp = client.query(queryReq);

List<QueryResp.QueryResult> results = queryResp.getQueryResults();
for (QueryResp.QueryResult result : results) {
    System.out.println(result.getEntity());
}
import { MilvusClient, DataType } from "@zilliz/milvus2-sdk-node";

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

// Query data and display the tsz field converted to "America/Havana"
const res = await client.query({
    collection_name: "my_collection",
    filter: 'id <= 10',
    output_fields: ["id", "tsz", "vec"],
    limit: 2,
    timezone: "America/Havana"
});
import (
    "context"
    "fmt"

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

ctx, cancel := context.WithCancel(context.Background())
defer cancel()

milvusAddr := "localhost:19530"
client, err := milvusclient.New(ctx, &milvusclient.ClientConfig{
    Address: milvusAddr,
})
if err != nil {
    fmt.Println(err.Error())
    // handle error
}
defer client.Close(ctx)

// Query data and display the tsz field converted to "America/Havana"
resultSet, err := client.Query(ctx, milvusclient.NewQueryOption("my_collection").
    WithFilter("id <= 10").
    WithLimit(2).
    WithTimeZone("America/Havana").
    WithOutputFields("id", "tsz", "vec"))
if err != nil {
    fmt.Println(err.Error())
    // handle error
}

fmt.Println("id: ", resultSet.GetColumn("id").FieldData().GetScalars())
fmt.Println("tsz: ", resultSet.GetColumn("tsz").FieldData().GetScalars())
fmt.Println("vec: ", resultSet.GetColumn("vec").FieldData().GetVectors())
export CLUSTER_ENDPOINT="http://localhost:19530"
export TOKEN="root:Milvus"

# Query data and display the tsz field converted to "America/Havana"
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/entities/query" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
--header "Request-Timeout: 10" \
-d '{
    "collectionName": "my_collection",
    "filter": "id <= 10",
    "limit": 2,
    "outputFields": ["id", "tsz", "vec"],
    "timezone": "America/Havana"
}'
#include "milvus/MilvusClientV2.h"
#include <iostream>

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

milvus::ConnectParam connect_param{"http://localhost:19530", "root:Milvus"};
auto status = client->Connect(connect_param);
if (!status.IsOk()) {
    std::cout << status.Message() << std::endl;
}

// Query data and display the tsz field converted to "America/Havana"
auto request = milvus::QueryRequest()
                   .WithCollectionName("my_collection")
                   .WithFilter("id <= 10")
                   .WithLimit(2)
                   .WithTimeZone("America/Havana")
                   .AddOutputField("id")
                   .AddOutputField("tsz")
                   .AddOutputField("vec");

milvus::QueryResponse response;
status = client->Query(request, response);
if (!status.IsOk()) {
    std::cout << status.Message() << std::endl;
}