RTREECompatible with Milvus 2.6.4+
RTREE インデックスは、Milvus のGEOMETRY フィールドに対するクエリを高速化するツリーベースのデータ構造です。コレクションに点、線、多角形などの幾何学オブジェクトがWell-known text (WKT)形式で格納されており、空間フィルタリングを高速化したい場合、RTREE は理想的な選択です。
仕組み
Milvusは、RTREE インデックスを使用し、2段階のプロセスでジオメトリデータを効率的に整理し、フィルタリングします:
フェーズ 1: インデックスの構築
リーフノードを作成します:各ジオメトリオブジェクトについて、そのオブジェクトを完全に含む最小の矩形であるMBR(Minimum Bounding Rectangle)を計算し、リーフノードとして格納します。
より大きなボックスにグループ化する:近くのリーフノードをまとめてクラスタ化し、各グループを新しいMBRでラップして内部ノードを形成します。たとえば、グループBにはDとE が含まれ、グループCにはFとG が含まれます。
ルート・ノードを追加します:MBRがすべての内部グループをカバーするルート・ノードを追加し、高さバランスのとれたツリー構造にします。
Retreeの仕組み
フェーズ2:クエリの高速化
クエリMBRの形成:クエリ・ジオメトリのMBRを計算します。
ブランチを刈り込みます:ルートから始めて、クエリMBRと各内部ノードを比較します。MBRがクエリMBRと交差しないブランチはスキップする。
候補を集める:交差するブランチに降りて、候補となるリーフ・ノードを集めます。
完全一致:各候補について、空間述語の完全一致を実行し、真の一致を決定します。
RTREE インデックスの作成
コレクションスキーマで定義されたGEOMETRY フィールドにRTREE インデックスを作成できます。
from pymilvus import MilvusClient
client = MilvusClient(uri="http://localhost:19530") # Replace with your server address
# Assume you have defined a GEOMETRY field named "geo" in your collection schema
# Prepare index parameters
index_params = client.prepare_index_params()
# Add RTREE index on the "geo" field
index_params.add_index(
field_name="geo",
index_type="RTREE", # Spatial index for GEOMETRY
index_name="rtree_geo", # Optional, name your index
params={} # No extra params needed
)
# Create the index on the collection
client.create_index(
collection_name="geo_demo",
index_params=index_params
)
RTREE によるクエリ
filter 式でジオメトリ演算子を使用してフィルタリングします。対象のGEOMETRY フィールドにRTREE が存在する場合、milvus はそれを使用して候補を自動的にプルーニングします。インデックスがない場合、フィルタはフルスキャンに戻ります。
使用可能なジオメトリ固有の演算子の完全なリストについては、ジオメトリ演算子を参照してください。
例 1:フィルタのみ
指定したポリゴン内のすべてのジオメトリ オブジェクトを検索します:
filter_expr = "ST_CONTAINS(geo, 'POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))')"
res = client.query(
collection_name="geo_demo",
filter=filter_expr,
output_fields=["id", "geo"],
limit=10
)
print(res) # Expected: a list of rows where geo is entirely inside the polygon
例 2: ベクトル検索 + 空間フィルタ
直線と交差する最も近いベクトルを検索します:
# Assume you've also created an index on "vec" and loaded the collection.
query_vec = [[0.1, 0.2, 0.3, 0.4, 0.5]]
filter_expr = "ST_INTERSECTS(geo, 'LINESTRING (1 1, 2 2)')"
hits = client.search(
collection_name="geo_demo",
data=query_vec,
limit=5,
filter=filter_expr,
output_fields=["id", "geo"]
)
print(hits) # Expected: top-k by vector similarity among rows whose geo intersects the line
GEOMETRY フィールドの使用方法については、Geometry Field を参照してください。
インデックスの削除
コレクションから既存のインデックスを削除するには、drop_index() メソッドを使用します。
v2.6.3以前では、スカラー・インデックスを削除する前にコレクションを解放する必要があります。
v2.6.4以降では、スカラー・インデックスが不要になったら直接削除できます。
client.drop_index(
collection_name="geo_demo", # Name of the collection
index_name="rtree_geo" # Name of the index to drop
)