BEACHSIDE BLOG

Azure と GitHub と C# が好きなエンジニアの個人メモ ( ・ㅂ・)و ̑̑

Cosmos DB: パーティションキー指定でデータを削除する

Cosmos DB の NoSQL を Vector Search のデータストアとして利用しているケースの Tips です (それ以外でもたくさん使いどころありますがw)。

例えばこんなとき。

  • データソースがファイル
  • ファイルの更新されたタイミングで (Vector store として利用している) Cosmos DB のデータを更新するような時。

対象がファイルのデータがチャンクされている場合、ファイルの変更によりチャンク数が減った場合にゴミが残るので、対象ファイルのデータはすべて削除した方がいいケースが多いです。

その際、Cosmos DB の Container のパーティションキーをファイル名やファイルのパスといった一意になる値にしておくと、パーティションキーを指定して一括削除が可能です。

(データモデリング的な観点で、ファイル単位でパーティションキーにすべきかどうかの検討はもちろん必要ですが)

ただ、この機能はいまだプレビュー中で利用にはちょっと手間がかかるのでメモしておきます。

前提

2025年2月時点ではプレビュー機能ということで注意点が書かれているので、本格的に利用を検討する際は必ず以下の公式ドキュメントを読みましょう。 また、FAQ で挙動の細かい話が書かれているので、そこもチェック必須です。

Delete items by partition key value using the Azure Cosmos DB SDK (preview) | Microsoft Learn

DeleteAllItemsByPartitionKey の有効化

2025年2月時点では、Azure Portal からの有効化の機能がないため、今回は Azure CLI で有効化していきます。

まずはAzure CLI でログインします。Azure Portal から Cloud Shell でやると楽そうですが、私はローカル環境から PowerShell を使って検証しています。

ということでいつもテナントが複数あってごちゃごちゃしてる場合はテナント指定でログインした方が楽な日々です。

az login --tenant xxxxxx

対象の Resource group と Cosmos DB のアカウント名を変数にいれておきますかね。

$resourceGroupName = "xxxxx"
$accountName = "xxxxxxx"

あとは、必要な情報を以下のコマンドで取得。

$cosmosdb = az cosmosdb show --resource-group $resourceGroupName --name $accountName
$capabilities = ($cosmosdb | ConvertFrom-Json).capabilities

$capabilities を見てみると、私の場合、2つを有効にしてるのでこんな感じ。

$capabilities

これに DeleteAllItemsByPartitionKey 追加するから以下かと思ったら、実行後エラーに。。。

# これだとあかん。
$capabilities += "DeleteAllItemsByPartitionKey"

ということで、$capabilities に直接 "DeleteAllItemsByPartitionKey" をセット。

$capabilities = "DeleteAllItemsByPartitionKey"

で、更新する。

az cosmosdb update --capabilities $capabilities -n $accountName -g $resourceGroupName

これで以下を実行すると、既存のやつは OFF にならず、既存の2つ + "DeleteAllItemsByPartitionKey" になってました。 不安で1時間後くらいに既存で有効化してた EnableNoSQLVectorSearchEnableNoSQLFullTextSearch が無効化されていないか確認しましたが大丈夫でした。

 az cosmosdb show --resource-group $resourceGroupName --name $accountName

Python で動作確認

5分くらいだと有効にならず、15分くらいしてから実行したら無事に partition key 指定で削除ができてました。 Jupyter notebook だとこんな感じかな。

# azure-cosmos と aiohttp の import 必要
from azure.cosmos.aio import CosmosClient

# 適当に初期化して...
cosmos_client = CosmosClient.from_connection_string(os.environ.get("COSMOS_CONNECTION"))
container_client = cosmos_client.get_database_client(os.environ.get("COSMOS_DB_NAME")).get_container_client(os.environ.get("COSMOS_CONTAINER_NAME"))

pk = "xxxxx"
await container_client.delete_all_items_by_partition_key(pk)