真のエンティティレベルの検索を解き放つ:Milvusの新しいArray-of-StructsとMAX_SIM機能
ベクター・データベースの上にAIアプリケーションを構築したことがある人なら、おそらく同じ痛点にぶつかったことがあるだろう。データベースは個々のチャンクの埋め込みを検索するが、アプリケーションはエンティティを気にする。このミスマッチが、検索ワークフロー全体を複雑にしている。
このような現象は、何度も何度も目にしてきたことだろう:
RAG知識ベース:RAG知識ベース:記事は段落埋め込みにチャンクされているため、検索エンジンは完全なドキュメントではなく、散らばった断片を返す。
Eコマースの推薦:商品には複数の画像エンベッディングがあり、システムは5つのユニークな商品ではなく、同じ商品の5つのアングルを返す。
動画プラットフォーム:動画はクリップ埋め込みに分割されているが、検索結果は単一の統合されたエントリではなく、同じ動画のスライスを表示する。
ColBERT / ColPaliスタイルの検索:ドキュメントは何百ものトークンやパッチレベルのエンベッディングに分割され、検索結果はまだマージが必要な小さな断片として戻ってくる。
これらの問題はすべて、同じアーキテクチャのギャップに起因しています。ほとんどのベクターデータベースは、各埋め込みを孤立した行として扱いますが、実際のアプリケーションは、ドキュメント、製品、ビデオ、アイテム、シーンなど、より高いレベルのエンティティを操作します。その結果、エンジニアリングチームは、重複排除、グループ化、バケツ分け、再ランク付けのロジックを使って手作業でエンティティを再構築せざるを得ない。それは機能しますが、壊れやすく、遅く、そもそもそこに存在すべきでないロジックでアプリケーションレイヤーを肥大化させます。
Milvus2.6.4では、このギャップを埋める新機能が追加された:MAX_SIMメトリックタイプを持つ構造体の配列です。これらにより、1つのエンティティのすべてのエンベッディングを1つのレコードに格納することができ、Milvusはエンティティのスコアリングを行い、総合的に返すことができます。重複した結果セットはもうありません。再ランク付けやマージのような複雑な後処理が不要になります。
この記事では、Array of StructsとMAX_SIMがどのように機能するかを説明し、2つの実例を通してデモンストレーションを行う:Wikipediaの文書検索とColPaliの画像ベースの文書検索だ。
Array of Structsとは?
Milvusでは、Array of Structsフィールドにより、1つのレコードに同じ定義済みのスキーマに従ったStruct要素の順序付きリストを格納することができます。Structは複数のベクトル、スカラーフィールド、文字列、その他サポートされている型を保持することができます。言い換えれば、1つのエンティティに属するすべての要素(段落埋め込み、画像ビュー、トークン・ベクトル、メタデータ)を1つの行に直接まとめることができます。
以下は、Array of Structsフィールドを含むコレクションのエンティティの例です。
{
'id': 0,
'title': 'Walden',
'title_vector': [0.1, 0.2, 0.3, 0.4, 0.5],
'author': 'Henry David Thoreau',
'year_of_publication': 1845,
// highlight-start
'chunks': [
{
'text': 'When I wrote the following pages, or rather the bulk of them...',
'text_vector': [0.3, 0.2, 0.3, 0.2, 0.5],
'chapter': 'Economy',
},
{
'text': 'I would fain say something, not so much concerning the Chinese and...',
'text_vector': [0.7, 0.4, 0.2, 0.7, 0.8],
'chapter': 'Economy'
}
]
// hightlight-end
}
上の例では、chunks フィールドが Array of Structs フィールドで、各 Struct 要素はそれ自身のフィールド、すなわちtext 、text_vector 、chapter を含んでいます。
このアプローチは、ベクトル・データベースにおける長年のモデリング問題を解決します。従来は、すべての埋め込みや属性がそれ自身の行になる必要があり、マルチベクターエンティティ(文書、製品、ビデオ)を数十、数百、あるいは数千のレコードに分割せざるを得ませんでした。Array of Structsを使えば、Milvusはマルチベクターエンティティ全体を1つのフィールドに格納することができますので、段落リスト、トークン埋め込み、クリップシーケンス、マルチビュー画像など、1つの論理アイテムが多くのベクターで構成されているようなシナリオに自然にフィットします。
MAX_SIM で構造体の配列はどのように機能するのか?
MAX_SIMは、この新しい構造体の配列の上に、意味検索のエンティティを意識させる新しいスコアリング戦略です。Milvusは、クエリが入力されると、それを各構造体配列内のすべてのベクトルと比較し、最大類似度をエンティティの最終スコアとする。そして、そのスコアに基づいてエンティティがランク付けされ、返される。これにより、散在した断片を検索するという古典的なベクトルデータベースの問題を回避し、グループ化、デデュープ、再ランク付けの負担をアプリケーションレイヤーに押し付けることができます。MAX_SIM によって、エンティティレベルの検索は、ビルトインで、一貫性があり、効率的なも のとなる。
MAX_SIM が実際にどのように機能するのかを理解するために、具体的な例を見てみよう。
注:この例では、すべてのベクトルは同じ埋め込みモデルによって生成され、類似度は [0,1] の範囲の余弦類似度で測定されます。
あるユーザーが"機械学習初心者コース "を検索したとします。
クエリは3つのトークンにトークン化される:
機械学習
初心者
コース
そして、それぞれのトークンは、ドキュメントに使われたのと同じ埋め込みモデルによって、埋め込みベクトルに変換される。
さて、ベクトル・データベースには2つの文書が含まれているとしよう:
doc_1: Pythonによるディープニューラルネットワーク入門ガイド
doc_2: LLM論文リーディング上級ガイド
どちらのドキュメントもベクトルに埋め込まれ、Array of Structsの中に格納されています。
ステップ1:doc_1のMAX_SIMの計算
各クエリベクトルに対して、milvusはdoc_1の各ベクトルとのコサイン類似度を計算する:
| はじめに | ガイド | ディープニューラルネットワーク | パイソン | |
|---|---|---|---|---|
| 機械学習 | 0.0 | 0.0 | 0.9 | 0.3 |
| 初心者 | 0.8 | 0.1 | 0.0 | 0.3 |
| コース | 0.3 | 0.7 | 0.1 | 0.1 |
各クエリベクトルに対して、MAX_SIM はその行から最も高い類似度を選択する:
機械学習 → ディープニューラルネットワーク (0.9)
初心者 → 導入 (0.8)
コース → ガイド (0.7)
最良の一致を合計すると、doc_1 のMAX_SIM スコアは 2.4 となる。
ステップ2:doc_2のMAX_SIMを計算する
次に、doc_2についてこのプロセスを繰り返す:
| 高度な | ガイド | LLM | 論文 | リーディング | |
|---|---|---|---|---|---|
| 機械学習 | 0.1 | 0.2 | 0.9 | 0.3 | 0.1 |
| 初心者 | 0.4 | 0.6 | 0.0 | 0.2 | 0.5 |
| コース | 0.5 | 0.8 | 0.1 | 0.4 | 0.7 |
doc_2のベストマッチは以下の通り:
「機械学習」 → 「LLM」 (0.9)
「初心者" → "ガイド" (0.6)
「コース」 → 「ガイド」 (0.8)
これらを合計すると、doc_2のMAX_SIMスコアは2.3となる。
ステップ3:スコアを比較する
2.4>2.3なので、doc_1はdoc_2より上位にランクされる。doc_1は機械学習入門ガイドに近いので、これは直感的に理解できる。
この例から、MAX_SIMの3つの核となる特徴を強調することができる:
キーワードベースではなく、意味ベース:MAX_SIMは、テキスト・リテラルではなく、埋め込みを比較する。機械学習」と「ディープニューラルネットワーク」は、重複する単語がゼロであっても、意味的類似度は0.9である。このため、MAX_SIMは同義語、言い換え、概念の重複、埋め込みが多い最新のワークロードに対してロバストです。
長さと順序に影響されない:MAX_SIMは、クエリとドキュメントのベクトル数が同じであることを要求しません(例えば、doc_1のベクトル数は4ですが、doc_2のベクトル数は5です。)また、ベクトルの順番も無視します。"beginner "がクエリで先に出てきても、"introduction "がドキュメントで後に出てきても、スコアには影響しません。
すべてのクエリベクトルが重要なのです:MAX_SIMは各クエリベクトルに最もマッチするものを選び、それらのベストスコアを合計します。これにより、一致しないベクトルが結果を歪めることを防ぎ、重要なクエリトークンが最終的なスコアに貢献することを保証します。例えば、doc_2の "beginner "の低品質なマッチは、そのまま全体のスコアを下げることになる。
ベクターデータベースにおいてMAX_SIM + 構造体の配列が重要な理由
Milvusはオープンソースの高性能ベクトルデータベースであり、現在ではArray of Structsと共にMAX_SIMを完全にサポートし、ベクトルネイティブなエンティティレベルのマルチベクトル検索を可能にしています:
マルチベクターエンティティをネイティブに保存Array of Structsにより、関連するベクトル群を別々の行や補助テーブルに分割することなく、単一のフィールドに格納することができます。
効率的なベストマッチ計算:IVFやHNSWのようなベクトルインデックスと組み合わせることで、MAX_SIMはすべてのベクトルをスキャンすることなく、ベストマッチを計算することができます。
意味を多用する作業負荷に特化した設計:このアプローチは、長文検索、多面的なセマンティックマッチング、文書と要約のアライメント、複数キーワードのクエリ、および柔軟できめ細かいセマンティック推論を必要とするその他のAIシナリオにおいて優れています。
構造体の配列を使用するタイミング
Array of Structsの価値は、それが何を可能にするかを見れば明らかだ。この機能の核心は、3つの基本的な機能を提供することである:
ベクトル、スカラー、文字列、メタデータといった異種データを単一の構造化オブジェクトに束ねる。
ストレージを実世界のエンティティに合わせるので、データベースの各行が、記事、製品、ビデオなどの実際のアイテムにきれいにマッピングされる。
MAX_SIMのような集約関数と組み合わせると、データベースから直接、真のエンティティレベルのマルチベクトル検索が可能になり、アプリケーションレイヤーでの重複排除、グループ化、再ランク付けが不要になる。
このような特性により、Array of Structs は、単一の論理エンティティが複数のベクタで表現される場合に自然に適合します。よくある例としては、段落に分割された記事、トークン埋め込みに分解された文書、複数の画像で表現された製品などがあります。検索結果が重複ヒットしたり、断片が散在したり、同じエンティティが検索結果の上位に何度も表示されたりする場合、Array of Structsは、アプリケーションコードで事後的にパッチを適用するのではなく、ストレージと検索のレイヤーでこれらの問題を解決します。
このパターンは、マルチベクトル検索に依存する最新のAIシステムにとって特に強力である。 例えば、ColBERTは1つのドキュメントを複数のベクトルとして表現する:
ColBERTは1つの文書を100~500のトークン埋め込みとして表現し、法律文書や学術研究などのドメイン間できめ細かなセマンティックマッチングを行う。
ColPaliは PDFの各ページを256~1024の画像パッチに変換 し、財務諸表、契約書、請求書、その他のスキャン文書を横断的に検索します。
Milvusは、Structsの配列により、これらのベクトルをすべて単一のエンティティに格納し、集約類似度(MAX_SIMなど)を効率的かつネイティブに計算することができます。これを明確にするために、2つの具体例を示します。
例1:Eコマースの商品検索
以前は、複数の画像を持つ商品は、1行に1つの画像を持つフラットスキーマに格納されていました。フロント、サイド、アングルの3つの画像を持つ商品は、3つの行を生成していました。検索結果は同じ商品の複数の画像を返すことが多く、手作業による重複排除と再ランク付けが必要でした。
Array of Structsでは、各商品が1行になります。すべての画像埋め込みとメタデータ(角度、is_primaryなど)は、構造体の配列として、images フィールド内に格納されます。milvusはそれらが同じ商品に属していると理解し、個々の画像ではなく商品全体を返します。
例2: ナレッジベースまたはウィキペディア検索
以前は、一つのウィキペディア記事がN個の段落行に分割されていました。検索結果は散らばった段落を返し、システムはそれらをグループ化し、どの記事に属するかを推測することを余儀なくされていました。
構造体の配列では、記事全体が1つの行になります。すべての段落とその埋め込みは段落フィールドの下にグループ化され、データベースは断片化された部分ではなく、記事全体を返します。
ハンズオンチュートリアル構造体の配列によるドキュメントレベルの検索
1.ウィキペディアのドキュメント検索
このチュートリアルでは、段落レベルのデータを完全なドキュメントレコードに変換するためにArray of Structsを使用する方法を説明します。
多くの知識ベースパイプラインはWikipediaの記事をパラグラフチャンクとして保存しています。これは埋め込みやインデックス作成には適していますが、検索には不向きです。ユーザクエリは通常、散らばった段落を返すため、手動で記事をグループ化し、再構築する必要があります。Array of StructsとMAX_SIMを使えば、各記事が1行になるようにストレージスキーマを再設計することができ、milvusは文書全体をネイティブにランク付けして返すことができる。
次のステップでは、以下の方法を紹介します:
ウィキペディアの段落データの読み込みと前処理
同じ記事に属するすべてのパラグラフを構造体の配列に束ねる。
これらの構造化されたドキュメントをmilvusに挿入する。
MAX_SIMクエリを実行し、重複排除や再ランク付けを行うことなく、クリーンな記事全体を取得する。
このチュートリアルが終わるころには、Milvusが直接エンティティレベルの検索を行うパイプラインが完成していることでしょう。
データモデル
{
"wiki_id": int, # WIKI ID(primary key)
"paragraphs": ARRAY<STRUCT< # Array of paragraph structs
text:VARCHAR # Paragraph text
emb: FLOAT_VECTOR(768) # Embedding for each paragraph
>>
}
ステップ 1: データのグループ化と変換
このデモではSimple Wikipedia Embeddingsデータセットを使用します。
import pandas as pd
import pyarrow as pa
# Load the dataset and group by wiki_id
df = pd.read_parquet(“train-*.parquet”)
grouped = df.groupby(‘wiki_id’)
# Build the paragraph array for each article
wiki_data = []
for wiki_id, group in grouped:
wiki_data.append({
‘wiki_id’: wiki_id,
‘paragraphs’: [{‘text’: row[‘text’], ‘emb’: row[‘emb’]}
for _, row in group.iterrows()]
})
ステップ2: Milvusコレクションの作成
from pymilvus import MilvusClient, DataType
client = MilvusClient(uri=“http://localhost:19530”)
schema = client.create_schema()
schema.add_field(“wiki_id”, DataType.INT64, is_primary=True)
# Define the Struct schema
struct_schema = client.create_struct_field_schema()
struct_schema.add_field(“text”, DataType.VARCHAR, max_length=65535)
struct_schema.add_field(“emb”, DataType.FLOAT_VECTOR, dim=768)
schema.add_field(“paragraphs”, DataType.ARRAY,
element_type=DataType.STRUCT,
struct_schema=struct_schema, max_capacity=200)
client.create_collection(“wiki_docs”, schema=schema)
ステップ3:データの挿入とインデックスの構築
# Batch insert documents
client.insert("wiki_docs", wiki_data)
# Create an HNSW index
index_params = client.prepare_index_params()
index_params.add_index(
field_name="paragraphs[emb]",
index_type=“HNSW”,
metric_type=“MAX_SIM_COSINE”,
params={“M”: 16, “efConstruction”: 200}
)
client.create_index(“wiki_docs”, index_params)
client.load_collection(“wiki_docs”)
ステップ4:ドキュメントの検索
# Search query
import cohere
from pymilvus.client.embedding_list import EmbeddingList
# The dataset uses Cohere’s multilingual-22-12 embedding model, so we must embed the query using the same model.
co = cohere.Client(f"<>" )
query = ‘Who founded Youtube’
response = co.embed(texts=[query], model=‘multilingual-22-12’)
query_embedding = response.embeddings
query_emb_list = EmbeddingList()
for vec in query_embedding[0]:
query_emb_list.add(vec)
results = client.search(
collection_name=“wiki_docs”,
data=[query_emb_list],
anns_field="paragraphs[emb]",
search_params={
“metric_type”: “MAX_SIM_COSINE”,
“params”: {“ef”: 200, “retrieval_ann_ratio”: 3}
},
limit=10,
output_fields=[“wiki_id”]
)
# Results: directly return 10 full articles!
for hit in results[0]:
print(f"Article {hit[‘entity’][‘wiki_id’]}: Score {hit[‘distance’]:.4f}")
出力の比較:従来の検索と構造体の配列の比較
Array of Structsの影響は、データベースが実際に何を返すかを見ると明らかになる:
| 次元 | 従来のアプローチ | 構造体の配列 |
|---|---|---|
| データベース出力 | 上位100段落を返す(冗長性が高い) | 上位10個の完全な文書を返す - クリーンで正確 |
| アプリケーションロジック | グループ化、重複排除、再ランク付けが必要(複雑) | 後処理は不要 - エンティティレベルの結果はmilvusから直接得られる。 |
ウィキペディアの例では、段落ベクトルを結合して統一的な文書表現にするという最も単純なケースのみを示した。しかし、Array of Structsの本当の強みは、古典的な検索パイプラインや最新のAIアーキテクチャなど、どのようなマルチベクトルデータモデルにも一般化できることです。
従来のマルチベクトル検索シナリオ
多くの確立された検索システムや推薦システムは、当然ながら複数の関連ベクトルを持つエンティティを操作します。Array of Structsはこれらのユースケースにうまく対応します:
| シナリオ | データモデル | エンティティごとのベクトル |
|---|---|---|
| 🛍️Eコマース商品 | 1つの商品 → 複数の画像 | 5-20 |
| 動画検索 | 1つの動画 → 複数のクリップ | 20-100 |
| 📖論文検索 | 一つの論文 → 複数のセクション | 5-15 |
AIモデルのワークロード(主要な複数ベクトルの使用例)
構造体の配列は、きめ細かな意味論的推論のためにエンティティごとに意図的に大きなベクトルセットを生成する最新のAIモデルでは、さらに重要になる。
| モデル | データモデル | エンティティごとのベクトル | アプリケーション |
|---|---|---|---|
| ColBERT | 1ドキュメント→多数のトークン埋め込み | 100-500 | 法律文書、学術論文、きめ細かな文書検索 |
| ColPali | PDF1ページ → 多数のパッチ埋め込み | 256-1024 | 財務報告書、契約書、請求書、マルチモーダル文書検索 |
これらのモデルは、マルチベクターストレージパターンを必要とする。Array of Structs以前は、開発者は行をまたいでベクトルを分割し、結果を手作業でつなぎ合わせる必要がありました。Milvusでは、MAX_SIMがドキュメントレベルのスコアリングを自動的に処理することで、これらのエンティティをネイティブに格納・検索できるようになりました。
2.ColPali画像ベース文書検索
ColPaliは、クロスモーダルなPDF検索のための強力なモデルです。テキストに依存する代わりに、各PDFページを画像として処理し、最大1024の視覚パッチにスライスし、パッチごとに1つの埋め込みを生成します。従来のデータベーススキーマでは、1つのページを数百から数千の別々の行として格納する必要があり、データベースがこれらの行が同じページに属することを理解することは不可能でした。その結果、エンティティレベルの検索は断片化し、実用的ではなくなります。
Array of Structsは、すべてのパッチ埋め込みを1つのフィールドに格納することで、この問題をきれいに解決し、milvusがページを1つのまとまったマルチベクターエンティティとして扱うことを可能にします。
従来のPDF検索は、ページ画像をテキストに変換するOCRに依存することがよくあります。これはプレーンテキストには有効ですが、図表、レイアウト、その他の視覚的な手がかりを失います。ColPaliは、ページ画像を直接処理することで、この制限を回避し、すべての視覚情報とテキスト情報を保持します。トレードオフはスケールです。各ページには数百のベクトルが含まれるようになり、多数の埋め込みを1つのエンティティに集約できるデータベースが必要になります-まさにArray of Structs + MAX_SIMが提供するものです。
最も一般的な使用例はVision RAGで、各PDFページがマルチベクターエンティティになります。典型的なシナリオは以下の通りです:
財務報告書:何千ものPDFから、特定のグラフや表を含むページを検索。
契約書:スキャンまたは撮影した法的文書から条項を検索。
請求書:ベンダー、金額、レイアウトで請求書を検索。
プレゼンテーション:特定の図やダイアグラムを含むスライドを検索。
データモデル:
{
"page_id": int, # Page ID (primary key)
"page_number": int, # Page number within the document
"doc_name": VARCHAR, # Document name
"patches": ARRAY<STRUCT< # Array of patch objects
patch_embedding: FLOAT_VECTOR(128) # Embedding for each patch
>>
}
ステップ1: データの準備ColPaliが画像やテキストをマルチベクトル表現に変換する方法の詳細については、ドキュメントを参照してください。
import torch
from PIL import Image
from colpali_engine.models import ColPali, ColPaliProcessor
model_name = “vidore/colpali-v1.3”
model = ColPali.from_pretrained(
model_name,
torch_dtype=torch.bfloat16,
device_map=“cuda:0”, # or “mps” if on Apple Silicon
).eval()
processor = ColPaliProcessor.from_pretrained(model_name)
# Example: 2 documents, 5 pages each, total 10 images
images = [
Image.open(“path/to/your/image1.png”),
Image.open(“path/to/your/image2.png”),
…
Image.open(“path/to/your/image10.png”)
]
# Convert each image into multiple patch embeddings
batch_images = processor.process_images(images).to(model.device)
with torch.no_grad():
image_embeddings = model(**batch_images)
ステップ2: Milvusコレクションの作成
from pymilvus import MilvusClient, DataType
client = MilvusClient(uri=“http://localhost:19530”)
schema = client.create_schema()
schema.add_field(“page_id”, DataType.INT64, is_primary=True)
schema.add_field(“page_number”, DataType.INT64)
schema.add_field(“doc_name”, DataType.VARCHAR, max_length=500)
# Struct Array for patches
struct_schema = client.create_struct_field_schema()
struct_schema.add_field(“patch_embedding”, DataType.FLOAT_VECTOR, dim=128)
schema.add_field(“patches”, DataType.ARRAY,
element_type=DataType.STRUCT,
struct_schema=struct_schema, max_capacity=2048)
client.create_collection(“doc_pages”, schema=schema)
ステップ3:データの挿入とインデックスの構築
# Prepare data for insertion
page_data=[
{
"page_id": 0,
"page_number": 0,
"doc_name": "Q1_Financial_Report.pdf",
"patches": [
{"patch_embedding": emb} for emb in image_embeddings[0]
],
},
...,
{
"page_id": 9,
"page_number": 4,
"doc_name": "Product_Manual.pdf",
"patches": [
{"patch_embedding": emb} for emb in image_embeddings[9]
],
},
]
client.insert(“doc_pages”, page_data)
# Create index
index_params = client.prepare_index_params()
index_params.add_index(
field_name="patches[patch_embedding]",
index_type=“HNSW”,
metric_type=“MAX_SIM_IP”,
params={“M”: 32, “efConstruction”: 200}
)
client.create_index(“doc_pages”, index_params)
client.load_collection(“doc_pages”)
ステップ4:クロスモーダル検索:テキストクエリ → 画像結果
# Run the search
from pymilvus.client.embedding_list import EmbeddingList
queries = [
“quarterly revenue growth chart”
]
# Convert the text query into a multi-vector representation
batch_queries = processor.process_queries(queries).to(model.device)
with torch.no_grad():
query_embeddings = model(**batch_queries)
query_emb_list = EmbeddingList()
for vec in query_embeddings[0]:
query_emb_list.add(vec)
results = client.search(
collection_name=“doc_pages”,
data=[query_emb_list],
anns_field="patches[patch_embedding]",
search_params={
“metric_type”: “MAX_SIM_IP”,
“params”: {“ef”: 100, “retrieval_ann_ratio”: 3}
},
limit=3,
output_fields=[“page_id”, “doc_name”, “page_number”]
)
print(f"Query: '{queries[0]}'")
for i, hit in enumerate(results, 1):
entity = hit[‘entity’]
print(f"{i}. {entity[‘doc_name’]} - Page {entity[‘page_number’]}")
print(f" Score: {hit[‘distance’]:.4f}\n")
サンプル出力:
Query: 'quarterly revenue growth chart'
1. Q1_Financial_Report.pdf - Page 2
Score: 0.9123
2. Q1_Financial_Report.pdf - Page 1
Score: 0.7654
3. Product_Manual.pdf - Page 1
Score: 0.5231
ここでは、結果は直接完全なPDFページを返します。Milvusがすべての集約を自動的に処理するため、1024パッチの埋め込みについて心配する必要はない。
結論
ほとんどのベクターデータベースは、各フラグメントを独立したレコードとして保存しているため、完全なドキュメント、製品、ページが必要なときに、アプリケーションはそれらのフラグメントを再組み立てしなければなりません。Structsの配列はそれを変えます。スカラー、ベクトル、テキスト、その他のフィールドを1つの構造化オブジェクトにまとめることで、1つのデータベース行で1つの完全なエンティティをエンドツーエンドで表現できるようになります。
アプリケーションレイヤーで複雑なグループ化、デデュープ、リランキングを必要としていた作業が、ネイティブなデータベース機能として利用できるようになるのです。ベクター・データベースの未来は、よりリッチな構造、よりスマートな検索、よりシンプルなパイプラインへと向かっています。
Array of StructsとMAX_SIMの詳細については、以下のドキュメントを参照してください:
Milvusの最新機能に関するご質問やディープダイブをご希望ですか?私たちの Discord チャンネルに参加するか、 GitHub に課題を提出してください。また、 Milvusオフィスアワーを通して、20分間の1対1のセッションを予約し、洞察やガイダンス、質問への回答を得ることもできます。
Try Managed Milvus for Free
Zilliz Cloud is hassle-free, powered by Milvus and 10x faster.
Get StartedLike the article? Spread the word



