メインコンテンツまでスキップ

クエリ

ANN 検索に加えて、Zilliz Cloud はクエリによるメタデータフィルタリングもサポートしています。このページでは、Query、Get、および QueryIterator を使用してメタデータフィルタリングを実行する方法を紹介します。

Notes

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

概要​

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

Get

Query

QueryIterator

適用シナリオ

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

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

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

フィルタリング方法

主キーによる

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

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

必須パラメーター

  • コレクション名

  • 主キー

  • コレクション名

  • フィルタリング式

  • コレクション名

  • フィルタリング式

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

オプションのパラメーター

  • パーティション名

  • 出力フィールド

  • パーティション名

  • 返すエンティティ数

  • 出力フィールド

  • パーティション名

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

  • 出力フィールド

戻り値

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

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

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

メタデータフィルタリングの詳細については、Filtering ExplainedFiltering Explained を参照してください。

Get の使用​

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

plaintext
[
{"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 でエンティティを取得できます。

python
from pymilvus import MilvusClient

client = MilvusClient(
uri="YOUR_CLUSTER_ENDPOINT",
token="YOUR_CLUSTER_TOKEN"
)

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

print(res)

Query の使用​

基本的な Query​

カスタムのフィルタリング条件でエンティティを検索する必要がある場合は、Query メソッドを使用します。以下のコード例では、id、vector、color という 3 つのフィールドがあり、red で始まる color 値を持つエンティティを、指定した数だけ返すことを前提としています。

python
from pymilvus import MilvusClient

client = MilvusClient(
uri="YOUR_CLUSTER_ENDPOINT",
token="YOUR_CLUSTER_TOKEN"
)

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

クエリ結果の並べ替え | ONDEMAND​

デフォルトでは、Query は結果を未指定の順序で返します。結果を 1 つ以上のスカラーフィールドで並べ替えるには、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 は大文字と小文字を区別する点に注意してください。

python
from pymilvus import MilvusClient

client = MilvusClient(
uri="YOUR_CLUSTER_ENDPOINT",
token="YOUR_CLUSTER_TOKEN"
)

# 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"],
)
plaintext
#include "milvus/MilvusClientV2.h"
#include <iostream>

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

milvus::ConnectParam connect_param{"YOUR_CLUSTER_ENDPOINT", "YOUR_CLUSTER_TOKEN"};
auto status = client->Connect(connect_param);
if (!status.IsOk()) {
std::cout << status.Message() << std::endl;
}

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

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

複数フィールドによる並べ替え​

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

python
# 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"],
)
plaintext
#include "milvus/MilvusClientV2.h"
#include <iostream>

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

milvus::ConnectParam connect_param{"YOUR_CLUSTER_ENDPOINT", "YOUR_CLUSTER_TOKEN"};
auto status = client->Connect(connect_param);
if (!status.IsOk()) {
std::cout << status.Message() << std::endl;
}

auto request = milvus::QueryRequest()
.WithCollectionName("my_collection")
.WithFilter("")
.WithLimit(10)
.AddOutputField("color")
.AddOutputField("rating")
.AddOutputField("price")
.WithOrderBy("rating:desc,price:asc");

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

並べ替えを使用したページネーション​

order_by を limit および offset と組み合わせて使用すると、並べ替えられた結果をページネーションできます。たとえば、価格順に並べ替えた商品リストを複数ページに表示する場合、各ページには正しい価格順で次のバッチの項目が重複や欠落なく表示されます。

python
# 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"],
)
plaintext
#include "milvus/MilvusClientV2.h"
#include <iostream>

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

milvus::ConnectParam connect_param{"YOUR_CLUSTER_ENDPOINT", "YOUR_CLUSTER_TOKEN"};
auto status = client->Connect(connect_param);
if (!status.IsOk()) {
std::cout << status.Message() << std::endl;
}

auto page1Req = milvus::QueryRequest()
.WithCollectionName("my_collection")
.WithFilter(R"(color like "red%")")
.WithLimit(5)
.WithOffset(0)
.AddOutputField("color")
.AddOutputField("price")
.WithOrderBy("price:asc");

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

auto page2Req = milvus::QueryRequest()
.WithCollectionName("my_collection")
.WithFilter(R"(color like "red%")")
.WithLimit(5)
.WithOffset(5)
.AddOutputField("color")
.AddOutputField("price")
.WithOrderBy("price:asc");

milvus::QueryResponse page2;
status = client->Query(page2Req, page2);
if (!status.IsOk()) {
std::cout << status.Message() << std::endl;
}
shell
# Zilliz CLI

クエリ結果の集計 | ONDEMAND​

クエリ結果を 1 つ以上のスカラーフィールドでグループ化し、グループごとに集計を計算できます。サポートされている集計演算子は count、min、max、sum、avg です。

group_by_fields を使用する際は、以下の点に注意してください。

  • group_by_fields でサポートされているフィールド型: INT8、INT16、INT32、INT64、VARCHAR、TIMESTAMPTZ。FLOAT、DOUBLE、ベクトル、JSON、または ARRAY フィールドでグループ化するとエラーが返されます。

  • sum と avg は数値のみを対象とします。これらを VARCHAR フィールドに適用するとエラーが返されます。

集計を有効にするには、group_by_fields を query() に渡し、集計式(count(*)、count(<field>)、min(<field>)、max(<field>)、sum(<field>)、avg(<field>))を output_fields に追加します。

以下の例では、color フィールドでエンティティをグループ化し、各色グループのエンティティ数を返します。

python
from pymilvus import MilvusClient

client = MilvusClient(
uri="YOUR_CLUSTER_ENDPOINT",
token="YOUR_CLUSTER_TOKEN"
)

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}]
plaintext
#include "milvus/MilvusClientV2.h"
#include <iostream>

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

milvus::ConnectParam connect_param{"YOUR_CLUSTER_ENDPOINT", "YOUR_CLUSTER_TOKEN"};
auto status = client->Connect(connect_param);
if (!status.IsOk()) {
std::cout << status.Message() << std::endl;
}

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

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

1 回の呼び出しで複数の集計式を要求できます。以下の例では、color でグループ化し、各グループの行数、平均価格、最大評価を返します。

python
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}]
plaintext
#include "milvus/MilvusClientV2.h"
#include <iostream>

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

milvus::ConnectParam connect_param{"YOUR_CLUSTER_ENDPOINT", "YOUR_CLUSTER_TOKEN"};
auto status = client->Connect(connect_param);
if (!status.IsOk()) {
std::cout << status.Message() << std::endl;
}

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

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

group_by_fields に複数のフィールドを渡すと、複合グループを計算できます。以下の例では、(color, rating) でグループ化し、各バケットの価格範囲を計算します。

python
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},
# ...]
plaintext
#include "milvus/MilvusClientV2.h"
#include <iostream>

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

milvus::ConnectParam connect_param{"YOUR_CLUSTER_ENDPOINT", "YOUR_CLUSTER_TOKEN"};
auto status = client->Connect(connect_param);
if (!status.IsOk()) {
std::cout << status.Message() << std::endl;
}

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

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

group_by_fields を limit と組み合わせて、返されるグループ数を制限することもできます。これは、フィールドのカーディナリティが高く、一部のバケットのみが必要な場合に便利です。

python
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}]
plaintext
#include "milvus/MilvusClientV2.h"
#include <iostream>

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

milvus::ConnectParam connect_param{"YOUR_CLUSTER_ENDPOINT", "YOUR_CLUSTER_TOKEN"};
auto status = client->Connect(connect_param);
if (!status.IsOk()) {
std::cout << status.Message() << std::endl;
}

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

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

QueryIterator の使用​

ページネーションされたクエリでカスタムのフィルタリング条件に一致するエンティティを検索する必要がある場合は、QueryIterator を作成し、その next() メソッドを使用してすべてのエンティティを反復処理し、フィルタリング条件を満たすエンティティを検索します。以下のコード例では、id、vector、color という 3 つのフィールドがあり、red で始まる color 値を持つすべてのエンティティを返すことを前提としています。

python
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

パーティション内でのクエリ​

Get、Query、または QueryIterator のリクエストにパーティション名を含めることで、1 つまたは複数のパーティション内でクエリを実行することもできます。以下のコード例では、コレクションに PartitionA という名前のパーティションがあることを前提としています。

python
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

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

データ探索や開発テストのためにコレクションから代表的なデータのサブセットを抽出するには、RANDOM_SAMPLE(sampling_factor) 式を使用します。ここで、sampling_factor は、サンプリングするデータの割合を表す 0 から 1 の間の浮動小数点数です。

Notes

詳細な使用方法、高度な例、ベストプラクティスについては、Random Sampling を参照してください。

python
# 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")

クエリのタイムゾーンを一時的に設定する​

コレクションに TIMESTAMPTZ フィールドがある場合は、クエリ呼び出しで timezone パラメーターを設定することで、単一の操作に対してデータベースまたはコレクションのデフォルトタイムゾーンを一時的に上書きできます。これは、操作中に TIMESTAMPTZ 値がどのように表示され、比較されるかを制御します。

timezone の値は、有効な IANA time zone identifier(たとえば、Asia/Shanghai, America/Chicago, または UTC)である必要があります。TIMESTAMPTZ フィールドの使用方法の詳細については、TIMESTAMPTZ Field を参照してください。

以下の例では、クエリ操作のタイムゾーンを一時的に設定する方法を示します。

python
# 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",
)