メインコンテンツまでスキップ
バージョン: User Guides (BYOC)

エンティティのアップサート

upsert 操作は、コレクションにエンティティを挿入または更新する便利な方法を提供します。

概要

upsert を使用して、新しいエンティティを挿入するか既存のエンティティを更新するかは、アップサートリクエストで提供された主キーがコレクションに存在するかどうかによって決まります。主キーが見つからない場合は、挿入操作が実行されます。それ以外の場合は、更新操作が実行されます。

アップサートリクエストは、挿入と削除を組み合わせたものです。既存のエンティティに対する upsert リクエストを受信すると、Zilliz Cloud はリクエストペイロードに含まれるデータを挿入し、同時にデータに指定された元の主キーを持つ既存のエンティティを削除します。

Q3LawAQIKht1FKbsM3EcoQAHnvc

対象のコレクションで主フィールドに autoid が有効になっている場合、Zilliz Cloud は挿入前にリクエストペイロードに含まれるデータ用に新しい主キーを生成します。

nullable が有効になっているフィールドについては、更新が不要な場合は upsert リクエストで省略できます。

マージモードでの Upsert

partial_update フラグを使用して、アップサートリクエストをマージモードで動作させることもできます。これにより、リクエストペイロードに更新が必要なフィールドのみを含めることができます。

NZNKwxm9ahmi87b487TcuCrNn4c

マージを実行するには、upsert リクエストで partial_updateTrue に設定し、主キーと新しい値で更新するフィールドを指定します。

このようなリクエストを受信すると、Zilliz Cloud は強い一貫性でクエリを実行してエンティティを取得し、リクエスト内のデータに基づいてフィールド値を更新し、変更されたデータを挿入してから、リクエストに含まれる元の主キーを持つ既存のエンティティを削除します。

フィールド値の更新

既存のエンティティのフィールド値を更新するには、マージモードでの upsert を使用します。このモードでは、リクエストに含まれるフィールドのみが更新され、他のすべてのフィールドは既存の値を保持します。

Upsert の動作: 特記事項

マージ機能を使用する前に考慮すべき特記事項がいくつかあります。以下のケースでは、titleissue という2つのスカラーフィールド、主キー id、および vector というベクトルフィールドを持つコレクションがあることを前提としています。

  • nullable が有効になっているフィールドのアップサート

    issue フィールドが null になりうると仮定します。これらのフィールドをアップサートする際、以下に注意してください:

    • upsert リクエストで issue フィールドを省略し、partial_update を無効にした場合、issue フィールドは元の値を保持するのではなく null に更新されます。

    • issue フィールドの元の値を保持するには、partial_update を有効にして issue フィールドを省略するか、upsert リクエストに元の値を含めて issue フィールドを含める必要があります。

  • 動的フィールド内のキーのアップサート

    例のコレクションで動的キーが有効になっており、エンティティの動的フィールド内のキーと値のペアが {"author": "John", "year": 2020, "tags": ["fiction"]} のようなものであると仮定します。

    authoryeartags などのキーでエンティティをアップサートする場合、または他のキーを追加する場合、以下に注意してください:

    • partial_update を無効にしてアップサートする場合、デフォルトの動作は 上書き です。これは、動的フィールドの値が、リクエストに含まれるすべてのスキーマ定義外のフィールドとその値によって上書きされることを意味します。

      例えば、リクエストに含まれるデータが {"author": "Jane", "genre": "fantasy"} の場合、対象エンティティの動的フィールド内のキーと値のペアはそれに更新されます。

    • partial_update を有効にしてアップサートする場合、デフォルトの動作は マージ です。これは、動的フィールドの値が、リクエストに含まれるすべてのスキーマ定義外のフィールドとその値とマージされることを意味します。

      例えば、リクエストに含まれるデータが {"author": "John", "year": 2020, "tags": ["fiction"]} の場合、アップサート後、対象エンティティの動的フィールド内のキーと値のペアは {"author": "John", "year": 2020, "tags": ["fiction"], "genre": "fantasy"} になります。

  • JSON フィールドのアップサート

    例のコレクションに extras というスキーマ定義の JSON フィールドがあり、この JSON フィールド内のキーと値のペアが {"author": "John", "year": 2020, "tags": ["fiction"]} のようなものであると仮定します。

    変更された JSON データでエンティティの extras フィールドをアップサートする場合、JSON フィールドは全体として扱われ、個別のキーを選択的に更新することはできないことに注意してください。言い換えれば、JSON フィールドは マージ モードのアップサートをサポートしません

制限と制約

上記の内容に基づき、以下の制限と制約に従う必要があります:

  • upsert リクエストには、常に対象エンティティの主キーを含める必要があります。

  • 対象のコレクションはロードされており、クエリが利用可能な状態である必要があります。

  • リクエストで指定されたすべてのフィールドは、対象コレクションのスキーマに存在する必要があります。

  • リクエストで指定されたすべてのフィールドの値は、スキーマで定義されたデータ型と一致する必要があります。

  • 関数を使用して別のフィールドから派生したフィールドについて、Zilliz Cloud はアップサート時に派生フィールドを削除して再計算を可能にします。

コレクション内のエンティティのアップサート

このセクションでは、my_collection という名前のコレクションにエンティティをアップサートします。このコレクションには idvectortitleissue という4つのフィールドがあります。id フィールドは主フィールドであり、titleissue フィールドはスカラーフィールドです。

コレクションに存在する場合、3つのエンティティはアップサートリクエストに含まれるものによって上書きされます。

from pymilvus import MilvusClient

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

data=[
{
"id": 0,
"vector": [-0.619954382375778, 0.4479436794798608, -0.17493894838751745, -0.4248030059917294, -0.8648452746018911],
"title": "Artificial Intelligence in Real Life",
"issue": "vol.12"
}, {
"id": 1,
"vector": [0.4762662251462588, -0.6942502138717026, -0.4490002642657902, -0.628696575798281, 0.9660395877041965],
"title": "Hollow Man",
"issue": "vol.19"
}, {
"id": 2,
"vector": [-0.8864122635045097, 0.9260170474445351, 0.801326976181461, 0.6383943392381306, 0.7563037341572827],
"title": "Treasure Hunt in Missouri",
"issue": "vol.12"
}
]

res = client.upsert(
collection_name='my_collection',
data=data
)

print(res)

# Output
# {'upsert_count': 3}

パーティション内のエンティティをアップサートする

指定されたパーティションにエンティティをアップサートすることもできます。以下のコードスニペットは、コレクション内に PartitionA という名前のパーティションが存在することを前提としています。

該当パーティション内に既存のエンティティが存在する場合、リクエストに含まれるエンティティによって上書きされます。

data=[
{
"id": 10,
"vector": [0.06998888224297328, 0.8582816610326578, -0.9657938677934292, 0.6527905683627726, -0.8668460657158576],
"title": "Layour Design Reference",
"issue": "vol.34"
},
{
"id": 11,
"vector": [0.6060703043917468, -0.3765080534566074, -0.7710758854987239, 0.36993888322346136, 0.5507513364206531],
"title": "Doraemon and His Friends",
"issue": "vol.2"
},
{
"id": 12,
"vector": [-0.9041813104515337, -0.9610546012461163, 0.20033003106083358, 0.11842506351635174, 0.8327356724591011],
"title": "Pikkachu and Pokemon",
"issue": "vol.12"
},
]

res = client.upsert(
collection_name="my_collection",
data=data,
partition_name="partitionA"
)

print(res)

# Output
# {'upsert_count': 3}

マージモードでエンティティをアップサートする

以下のコード例は、部分的な更新(partial updates)を伴うエンティティのアップサート方法を示しています。更新が必要なフィールドとその新しい値のみを提供し、明示的に部分更新フラグを指定します。

以下の例では、アップサートリクエストで指定されたエンティティの issue フィールドが、リクエストに含まれる値に更新されます。

📘Notes

マージモードでアップサートを実行する際は、リクエストに関与するエンティティが同一のフィールドセットを持つことを確認してください。たとえば、以下のコードスニペットのように2つ以上のエンティティをアップサートする場合、エラーを防ぎデータの整合性を維持するために、それらが同一のフィールドを含んでいることが重要です。

data=[
{
"id": 1,
"issue": "vol.14"
},
{
"id": 2,
"issue": "vol.7"
}
]

res = client.upsert(
collection_name="my_collection",
data=data,
partial_update=True
)

print(res)

# Output
# {'upsert_count': 2}