クエリ

Milvusでは、ANN検索に加え、クエリによるメタデータフィルタリングもサポートしています。このページでは、Query、Get、およびQueryIteratorsを使用して、エンティティの取得、メタデータのフィルタリング、クエリ結果のソート、スカラー値の集計を行う方法について説明します。

コレクションの作成後に新しいフィールドを追加した場合、これらのフィールドを含むクエリでは、値が明示的に設定されていないエンティティに対して、定義されたデフォルト値またはNULL が返されます。詳細については、「コレクションスキーマの変更」を参照してください。

概要

コレクションには、さまざまなタイプのスカラーフィールドを格納できます。Milvus では、1 つまたは複数のスカラーフィールドに基づいてエンティティをフィルタリングできます。Milvus では、Query、Get、QueryIterator の 3 種類のクエリが提供されています。以下の表に、これら 3 種類のクエリの比較を示します。

Get

Query

QueryIterator

適用可能なシナリオ

指定された主キーを持つエンティティを検索する場合。

カスタムフィルタリング条件を満たすエンティティをすべて、または指定した数だけ検索する場合

ページネーションされたクエリにおいて、カスタムフィルタリング条件を満たすすべてのエンティティを検索する場合。

フィルタリング方法

主キーによるフィルタリング

フィルタリング式によるフィルタリング。

フィルタリング式によるフィルタリング。

必須パラメータ

  • コレクション名

  • 主キー

  • コレクション名

  • フィルタリング式

  • コレクション名

  • フィルタリング式コレクション名

  • クエリごとに返すエンティティ数

オプションのパラメータ

  • パーティション名

  • 出力フィールド

  • パーティション名

  • クエリごとに返すエンティティの数

  • 出力フィールド

  • パーティション名

  • 合計で返すエンティティ数

  • 出力フィールド

返される内容

指定されたコレクションまたはパーティション内で、指定された主キーを持つエンティティを返します。

指定されたコレクションまたはパーティション内で、カスタムフィルタリング条件を満たすすべてのエンティティ、または指定された数のエンティティを返します。

ページネーションされたクエリを通じて、指定されたコレクションまたはパーティション内で、カスタムフィルタリング条件を満たすすべてのエンティティを返します。

メタデータによるフィルタリングの詳細については、「ブール式ルール」を参照してください。

Get の使用

プライマリキーでエンティティを検索する必要がある場合は、Getメソッドを使用できます。以下のコード例では、コレクションに「id 」、「vector 」、および「color 」という 3 つのフィールドが存在することを前提としています。

[
        {"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 という3つのフィールドが存在することを前提としており、red で始まるcolor の値を持つエンティティを指定された数だけ返します。

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 パラメータを使用すると、1つまたは複数のスカラーフィールドに基づいて結果を並べ替えることができます。order_by を使用する際は、以下の点に注意してください:

  • order_by limit と組み合わせて使用する必要があります。

  • サポートされているフィールド型:INT8 、INT16 、INT32 、INT64 、FLOAT 、DOUBLE 、およびVARCHAR 。ベクトル、JSON 、またはARRAY フィールドによるソートはサポートされていません。

  • NULL 許容フィールドでソートする場合、昇順(NULLS LAST)では NULL 値が末尾に、降順(NULLS FIRST)では先頭に配置されます。

基本的なソート

order_by パラメータに、"field_name:direction" 形式の文字列のリストを渡します。この際、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;
}

複数フィールドによるソート

複数のフィールドを一度に指定して並べ替えることができます。結果はまず、リストの最初のフィールドに基づいて並べ替えられます。そのフィールドの値が同じ行が2つある場合、2番目のフィールドによって順序が決まり、以下同様に処理されます。

# 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

クエリ結果を1つ以上のスカラーフィールドでグループ化し、グループごとの集計を計算できます。サポートされている集計演算子は、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;
}

1回の呼び出しで複数の集計式を指定できます。次の例では、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 という3つのフィールドが存在することを前提としており、red で始まるcolor の値を持つすべてのエンティティを返します。

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リクエストにパーティション名を含めることで、1つまたは複数のパーティション内でクエリを実行することもできます。以下のコード例では、コレクション内に「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;
}

Query を使用したランダムサンプリング

データ探索や開発テストのためにコレクションから代表的なデータサブセットを抽出するには、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;
}

翻訳DeepL

マネージド Milvus を無料で試す

Zilliz Cloud は手間いらず、Milvus を基盤に 10 倍高速です。

始める
フィードバック

このページは役に立ちましたか ?