今回ははAzure Cosmos DB, C# Core 2x からのアクセスと管理をまとめます。
Cosmos DB?
Cosmos DBはAzureファミリーが提供するNoSQL型データベースです。詳しくはこちらをご参照ください。https://docs.microsoft.com/ja-jp/azure/cosmos-db/introduction
開発側としてはSQLのようにデータベースのスキーマを更新する必要がなく手軽で便利であります。NoSQLの良さや特徴はまた別の機会にまとめたいと思います。
Cosmos DBの構成
Cosmos DBには基本構成概念として、
Database
> Collection
> Document
というものがあります。値段はCollectionのグレードによって設定されています。
事前準備
まずはAzure のアカウントが必要です。持っているAzureアカウントからCosmos DBを検索してCosmos DBアカウントを開設してください(ここの手順は一旦スキップ)。その他に事前にNuGetパッケージをプロジェクトにインストールする必要があります。
Cosmos DBにアクセスするためのキーを appsettings.json
に保存します。
Databaseの管理
ではさっそく最高層にいるDatabase
の管理から。
まずはDatabase
の作成
/// <summary>
/// Create Database
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public async Task<Database> CreateDatabase(string id)
{
client = new DocumentClient(new Uri(_config.Value.CosmoDbSettings.endpoint),
_config.Value.CosmoDbSettings.key);
var database = await client.CreateDatabaseAsync(new Database { Id = id });
return database;
}
作成したDatabase
の取得
/// <summary>
/// Get specific Database
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public Database GetDatabase(string id)
{
client = new DocumentClient(new Uri(_config.Value.CosmoDbSettings.endpoint),
_config.Value.CosmoDbSettings.key);
Database database = client.CreateDatabaseQuery().Where(db => db.Id == id).AsEnumerable().FirstOrDefault();
return database;
}
毎度client
を作るのは面倒なので、client
生成をclass
化して、次はDatabase
の一覧を取得。
/// <summary>
/// Get list of Databases
/// </summary>
/// <returns></returns>
public List<Database> GetListOfDatabases()
{
return GetClient().ReadDatabaseFeedAsync().Result.ToList();
}
最後にDatabase
の削除
/// <summary>
/// Delete Databae
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public async Task DeleteDatabase(string id)
{
await GetClient().DeleteDatabaseAsync(UriFactory.CreateDatabaseUri(id));
}
Collectionの管理
次はCollection
の管理です。Cosmos DBの価格のCollection
のTier
に連動しています。通常Collection
を作成するとS1
に設定されています。現在のTier
が何か確認するメソッドと、アップグレードダウングレードできるメソッドも書いてみます。
まずは、Collectionの作成
/// <summary>
/// Create collection
/// </summary>
/// <param name="databaseId"></param>
/// <param name="collectionId"></param>
/// <returns></returns>
public async Task<DocumentCollection> CreateCollection(string databaseId, string collectionId)
{
var database = GetDatabase(databaseId);
// Default is S1 tier
return await GetClient().CreateDocumentCollectionAsync(database.SelfLink, new DocumentCollection { Id = collectionId });
}
作成したCollectionのTierを確認
/// <summary>
/// Get Collectoin tier
/// </summary>
/// <param name="databaseId"></param>
/// <param name="collectionId"></param>
/// <returns></returns>
public Offer GetCurrentCollectionTier(string databaseId, string collectionId)
{
var database = GetDatabase(databaseId);
var collection = GetClient().CreateDocumentCollectionQuery(database.SelfLink).Where(c => c.Id == collectionId).ToArray().FirstOrDefault();
return GetClient().CreateOfferQuery().Where(o => o.ResourceLink == collection.SelfLink).AsEnumerable().Single();
}
次は指定のCollection + Tierに変更。
/// <summary>
/// Set Collection tier
/// </summary>
/// <param name="databaseId"></param>
/// <param name="collectionId"></param>
/// <param name="tier"></param>
/// <returns></returns>
public async Task<Offer> SetCollectionTier(string databaseId, string collectionId, string tier)
{
// Get Collection
var collection = GetCollection(databaseId, collectionId);
// Get Tier of Collection
var offer = GetCurrentCollectionTier(collection);
// Set New OfferType
offer.OfferType = tier;
// Replace
var replaced = await GetClient().ReplaceOfferAsync(offer);
// Get Collection Again
collection = GetCollection(databaseId, collectionId);
// Get new Offer and return
return GetClient().CreateOfferQuery().Where(o => o.ResourceLink == collection.SelfLink).AsEnumerable().Single();
}
次にDatabase内にあるすべてのCollectionを表示するメソッド
/// <summary>
/// Get list of Collections in Database
/// </summary>
/// <param name="databaseId"></param>
/// <returns></returns>
public async Task<List<DocumentCollection>> GetCollectionResource(string databaseId)
{
var collections = await GetClient().ReadDocumentCollectionFeedAsync(UriFactory.CreateDatabaseUri(databaseId));
return collections.ToList();
}
では、最後にCollectionを削除
/// <summary>
/// Delete collection
/// </summary>
/// <param name="databaseId"></param>
/// <param name="collectionId"></param>
/// <returns></returns>
public async Task DeleteCollection(string databaseId, string collectionId)
{
// Get Collection
var collection = GetCollection(databaseId, collectionId);
await GetClient().DeleteDocumentCollectionAsync(collection.SelfLink);
}
Documentの管理
最後にDocumentの作成、編集、検索、削除を見てみます。
Documentの作成
/// <summary>
/// Write Document
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="databaseId"></param>
/// <param name="collectionId"></param>
/// <param name="document"></param>
/// <returns></returns>
public async Task<ResourceResponse<Document>> WriteDocumentAsync<T>(string databaseId, string collectionId, T document)
{
var createdDocument = await GetClient().CreateDocumentAsync(UriFactory.CreateDocumentCollectionUri(databaseId, collectionId).ToString(), collection.SelfLink, document);
return createdDocument;
}
次にDocumentの検索
/// <summary>
/// Get T
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="databaseId"></param>
/// <param name="collectionId"></param>
/// <param name="query"></param>
/// <returns></returns>
public List<T> GetDocuments<T>(string databaseId, string collectionId, string query)
{
var document = GetClient().CreateDocumentQuery<T>(UriFactory.CreateDocumentCollectionUri(databaseId,collectionId), query);
return document.ToList();
}
ここにあるquery
はSQL文をそのまま使うことができます。
最後に
今日は以上です。このコラムは継続的にアップデートしていきたいと思います。