適用対象: MongoDB
このチュートリアルでは、Azure Cosmos DB にデータを格納するときに Mongoose フレームワークを使用する方法について説明します。 このチュートリアルでは、Azure Cosmos DB の MongoDB 用 API を使用します。 知らない場合に備えて説明すると、Mongoose は、Node.js での MongoDB 用のオブジェクト モデル化フレームワークです。アプリケーション データをモデル化するための単純なスキーマベース ソリューションが提供されます。
Azure Cosmos DB は、Microsoft のグローバルに分散されたマルチモデル データベース サービスです。 Azure Cosmos DB の中核をなすグローバル配布と水平方向のスケール機能を活用して、ドキュメント、キー/値、およびグラフ データベースをすばやく作成および照会できます。
前提条件
Azure サブスクリプションをお持ちでない場合は、開始する前に Azure 無料アカウントを作成してください。
Azure サブスクリプション不要で、契約もなしで Azure Cosmos DB を無料で試すことができます。 または、Azure Cosmos DB Free レベルのアカウントを作成して、最初の 1000 RU/秒と 25 GB のストレージを無料でご利用いただけます。 また、URI https://localhost:8081
で Azure Cosmos DB エミュレーターを使用することもできます。 エミュレーターで使用するキーについては、「要求の認証」を参照してください。
Node.js バージョン v0.10.29 以降
Azure Cosmos DB アカウントを作成する
それでは、Azure Cosmos DB アカウントを作成してみましょう。 使用するアカウントが既にある場合は、「Node.js アプリケーションをセットアップする」に進んでかまいません。 Azure Cosmos DB Emulator を使用する場合は、Azure Cosmos DB Emulator に関する記事に記載されている手順に従ってエミュレーターをセットアップし、「Node.js アプリケーションをセットアップする」に進んでください。
新しいブラウザー ウィンドウで、Azure Portal にサインインします。
左側のメニューで、 [リソースの作成] を選択します。
[新規] ページで、[データベース]>[Azure Cosmos DB] の順に選択します。
[API オプションの選択] ページで、[Azure Cosmos DB for MongoDB]>[作成] を選択します。
API によって、作成するアカウントの種類が決まります。 このクイックスタートでは MongoDB に対応するコレクションを作成するので、Azure Cosmos DB for MongoDB を選択します。 詳細については、Azure Cosmos DB for MongoDB の概要に関するページを参照してください。
[Azure Cosmos DB アカウントの作成] ページで、新しい Azure Cosmos DB アカウントの設定を入力します。
設定 値 説明 サブスクリプション サブスクリプション名 この Azure Cosmos DB アカウントに使用する Azure サブスクリプションを選択します。 リソース グループ リソース グループ名 リソース グループを選択するか、 [新規作成] を選択し、新しいリソース グループの一意の名前を入力します。 アカウント名 一意の名前を入力します 自分の Azure Cosmos DB アカウントを識別するための一意の名前を入力します。 アカウント URI は、一意のアカウント名に mongo.cosmos.azure.com が追加されたものになります。
アカウント名に使用できるのは、小文字、数字、ハイフン (-) のみで、長さは 3 文字から 44 文字の範囲にする必要があります。場所 ユーザーに最も近いリージョン Azure Cosmos DB アカウントをホストする地理的な場所を選択します。 データに最も高速にアクセスできるよう、お客様のユーザーに最も近い場所を使用します。 容量モード プロビジョニング スループットまたはサーバーレス プロビジョニング スループット モードでアカウントを作成するには、 [Provisioned throughput](プロビジョニング スループット) を選択します。 サーバーレス モードでアカウントを作成するには、 [サーバーレス] を選択します。
注: サーバーレス アカウントでサポートされているのは、MongoDB 用 API バージョン 4.2、4.0、3.6 のみです。 バージョンとして 3.2 を選択すると、アカウントにプロビジョニング済みスループット モードが強制されます。Apply Azure Cosmos DB free tier discount (Azure Cosmos DB Free レベル割引を適用する) [適用] または [適用しない] Azure Cosmos DB Free レベルのアカウントでは、最初の 1000 RU/s と 25 GB のストレージを無料でご利用いただけます。 Free レベルの詳細を確認してください。 バージョン 必要なサーバー バージョンを選択する Azure Cosmos DB for MongoDB は、サーバー バージョン 4.2、4.0、3.6、3.2 と互換性があります。 アカウントは、作成した後にアップグレードまたはダウングレードできます。 Note
Azure サブスクリプションにつき所有できる Free レベルの Azure Cosmos DB アカウントは 1 つまでです。また、アカウントの作成時にオプトインする必要があります。 Free レベルの割引を適用するオプションが表示されない場合は、サブスクリプション内の別のアカウントが Free レベルで既に有効になっていることを意味します。
[グローバル分散] タブで、次の詳細を構成します。 このクイックスタートでは、既定値のままでかまいません。
設定 値 説明 geo 冗長性 無効化 リージョンをペア リージョンとペアリングすることによる、アカウントでのグローバル配信を有効または無効にします。 アカウントには、後でさらにリージョンを追加できます。 マルチリージョン書き込み 無効化 マルチリージョン書き込み機能を使用すると、世界中のデータベースとコンテナーで、プロビジョニングされたスループットを利用できます。 Note
[Capacity mode](容量モード) として [サーバーレス] を選択した場合、以下のオプションは利用できません。
- Apply Free Tier Discount (Free レベルの割引の適用)
- geo 冗長性
- マルチリージョン ライター
必要に応じて、次のタブで追加の詳細を構成できます。
- [ネットワーク] - 仮想ネットワークからのアクセスを構成します。
- [バックアップ ポリシー] - 定期的または継続的のいずれかのバックアップ ポリシーを構成します。
- [暗号化] - サービス マネージド キーまたはカスタマー マネージド キーのいずれかを使用します。
- [タグ] - タグは名前と値のペアで、同じタグを複数のリソースやリソース グループに適用することでリソースを分類したり、統合した請求を表示したりできるようにします。
[Review + create](レビュー + 作成) を選択します。
アカウントの作成には数分かかります。 ポータルに [Congratulations! Your Azure Cosmos DB for MongoDB account is ready] (おめでとうございます。Azure Cosmos DB for MongoDB アカウントの準備が完了しました) ページが表示されるのを待ちます。
データベースを作成する
このアプリケーションでは、Azure Cosmos DB でコレクションを作成する 2 つの方法について説明します。
各オブジェクト モデルを個別のコレクションに格納する:専用のスループットを使用してデータベースを作成することをお勧めします。 この容量モデルを使用すると、コスト効率が向上します。
すべてのオブジェクト モデルを 1 つの Azure Cosmos DB コレクションに格納する: すべてのモデルを 1 つのコレクションに格納する場合は、[スループットのプロビジョニング] オプションを選択せずに、新しいデータベースを作成できます。 この容量モデルを使用すると、すべてのオブジェクト モデルに対して独自のスループット容量を持つ各コレクションが作成されます。
データベースを作成したら、以下の COSMOSDB_DBNAME
環境変数で名前を使用します。
Node.js アプリケーションをセットアップする
Note
アプリケーションをセットアップするのではなくサンプル コードを確認するだけの場合は、このチュートリアルで使用されるサンプルを複製して、Node.js Mongoose アプリケーションを Azure Cosmos DB 上に構築します。
選択したフォルダーに Node.js アプリケーションを作成するには、ノードのコマンド プロンプトで次のコマンドを実行します。
npm init
質問に回答すると、プロジェクトが準備完了になります。
新しいファイルをフォルダーに追加し、名前を
index.js
にします。次の
npm install
オプションのいずれかを使用して、必要なパッケージをインストールします。- Mongoose:
npm install mongoose --save
Note
MongoDB サーバー バージョン用 API と互換性のある mongoose のバージョンの詳細については、Mongoose の互換性に関するページを参照してください。
Dotenv (.env ファイルからシークレットを読み込む場合):
npm install dotenv --save
Note
--save
フラグによって、package.json ファイルに依存関係が追加されます。
- Mongoose:
index.js
ファイルに依存関係をインポートします。var mongoose = require('mongoose'); var env = require('dotenv').config(); //Use the .env file to load the variables
Azure Cosmos DB の接続文字列と Azure Cosmos DB の名前を
.env
ファイルに追加します。 プレースホルダー {cosmos-account-name} および {dbname} を独自の Azure Cosmos DB アカウント名およびデータベース名に置き換えます。このとき、中かっこ記号は入力しません。// You can get the following connection details from the Azure portal. You can find the details on the Connection string pane of your Azure Cosmos DB account. COSMOSDB_USER = "<Azure Cosmos DB account's user name, usually the database account name>" COSMOSDB_PASSWORD = "<Azure Cosmos DB account password, this is one of the keys specified in your account>" COSMOSDB_DBNAME = "<Azure Cosmos DB database name>" COSMOSDB_HOST= "<Azure Cosmos DB Host name>" COSMOSDB_PORT=10255
Mongoose フレームワークを使用して Azure Cosmos DB に接続するには、次のコードを index.js の末尾に追加します。
mongoose.connect("mongodb://"+process.env.COSMOSDB_HOST+":"+process.env.COSMOSDB_PORT+"/"+process.env.COSMOSDB_DBNAME+"?ssl=true& replicaSet=globaldb", { auth: { username: process.env.COSMOSDB_USER, password: process.env.COSMOSDB_PASSWORD }, useNewUrlParser: true, useUnifiedTopology: true, retryWrites: false }) .then(() => console.log('Connection to CosmosDB successful')) .catch((err) => console.error(err));
Note
ここで、環境変数は、 npm パッケージを使用して process.env.{variableName} によって読み込まれます。
Azure Cosmos DB に接続したら、Mongoose でのオブジェクト モデルのセットアップを開始できます。
Azure Cosmos DB で Mongoose を使用するためのベスト プラクティス
ユーザーが作成するすべてのモデルに対して、Mongoose は新しいコレクションを作成します。 これは、以前に説明したデータベース レベルのスループット オプションを使用して解決することをお勧めします。 1 つのコレクションを使用するには、Mongoose Discriminators を使用する必要があります。 ディスクリミネーターはスキーマ継承メカニズムです。 これにより、基礎となる同一の MongoDB コレクション上で、スキーマが重複する複数のモデルを持つことが可能になります。
同一コレクション内にさまざまなデータ モデルを格納でき、クエリの際にはフィルター句を使用して必要なデータのみをプルダウンできます。 各モデルについて説明します。
オブジェクト モデルごとに 1 つのコレクション
このセクションでは、Azure Cosmos DB の MongoDB 用 API でこれを実現する方法について説明します。 コストと容量を制御できるため、この方法をお勧めします。 その結果、データベースの要求ユニットの数は、オブジェクト モデルの数に左右されなくなります。 これは Mongoose の既定の動作モデルなので、慣れているかもしれません。
再び、
index.js
を開きます。'Family' のスキーマ定義を作成します。
const Family = mongoose.model('Family', new mongoose.Schema({ lastName: String, parents: [{ familyName: String, firstName: String, gender: String }], children: [{ familyName: String, firstName: String, gender: String, grade: Number }], pets:[{ givenName: String }], address: { country: String, state: String, city: String } }));
'Family' のオブジェクトを作成します。
const family = new Family({ lastName: "Volum", parents: [ { firstName: "Thomas" }, { firstName: "Mary Kay" } ], children: [ { firstName: "Ryan", gender: "male", grade: 8 }, { firstName: "Patrick", gender: "male", grade: 7 } ], pets: [ { givenName: "Buddy" } ], address: { country: "USA", state: "WA", city: "Seattle" } });
最後に、オブジェクトを Azure Cosmos DB に保存します。 これによりコレクションが自動的に作成されます。
family.save((err, saveFamily) => { console.log(JSON.stringify(saveFamily)); });
次に、別のスキーマとオブジェクトを作成します。 ここでは、家族連れ向けの行楽地 (Vacation Destinations) に対応するものを作成します。
前回と同じように、まずスキーマを作成します。
const VacationDestinations = mongoose.model('VacationDestinations', new mongoose.Schema({ name: String, country: String }));
サンプル オブジェクトを作成して保存します (このスキーマには複数のオブジェクトを追加できます)。
const vacaySpot = new VacationDestinations({ name: "Honolulu", country: "USA" }); vacaySpot.save((err, saveVacay) => { console.log(JSON.stringify(saveVacay)); });
ここで、Azure Portal に移動すると、Azure Cosmos DB に 2 つのコレクションが作成されていることがわかります。
最後に、Azure Cosmos DB からデータを読み取ります。 既定の Mongoose 処理モデルを使用しているため、読み取り方法は Mongoose の他の読み取りと同じです。
Family.find({ 'children.gender' : "male"}, function(err, foundFamily){ foundFamily.forEach(fam => console.log("Found Family: " + JSON.stringify(fam))); });
Mongoose ディスクリミネーターを使用して 1 つのコレクションにデータを格納する
この方法では、各コレクションのコストを最適化しやすくするために Mongoose ディスクリミネーターを使用します。 ディスクリミネーターによって、識別するための "キー" を定義することができ、このキーを使用して、さまざまなオブジェクト モデルでの格納、識別、フィルター処理が可能になります。
ここでは、ベース オブジェクト モデルを作成し、識別キーを定義し、ベース モデルに拡張子として 'Family' と 'VacationDestinations' を追加します。
基本構成を設定し、ディスクリミネーター キーを定義します。
const baseConfig = { discriminatorKey: "_type", //If you've got a lot of different data types, you could also consider setting up a secondary index here. collection: "alldata" //Name of the Common Collection };
次は、共通オブジェクト モデルを定義します。
const commonModel = mongoose.model('Common', new mongoose.Schema({}, baseConfig));
ここで 'Family' モデルを定義します。
mongoose.model
の代わりにcommonModel.discriminator
を使用していることに注意してください。 さらに、Mongoose スキーマに基本構成を追加します。 次のように、discriminatorKey はFamilyType
になります。const Family_common = commonModel.discriminator('FamilyType', new mongoose.Schema({ lastName: String, parents: [{ familyName: String, firstName: String, gender: String }], children: [{ familyName: String, firstName: String, gender: String, grade: Number }], pets:[{ givenName: String }], address: { country: String, state: String, city: String } }, baseConfig));
同様に、'VacationDestinations' に対してもう 1 つのスキーマを追加します。 ここでは、DiscriminatorKey は
VacationDestinationsType
です。const Vacation_common = commonModel.discriminator('VacationDestinationsType', new mongoose.Schema({ name: String, country: String }, baseConfig));
最後に、モデルのオブジェクトを作成して保存します。
'Family' モデルにオブジェクトを追加します。
const family_common = new Family_common({ lastName: "Volum", parents: [ { firstName: "Thomas" }, { firstName: "Mary Kay" } ], children: [ { firstName: "Ryan", gender: "male", grade: 8 }, { firstName: "Patrick", gender: "male", grade: 7 } ], pets: [ { givenName: "Buddy" } ], address: { country: "USA", state: "WA", city: "Seattle" } }); family_common.save((err, saveFamily) => { console.log("Saved: " + JSON.stringify(saveFamily)); });
次に、'VacationDestinations' モデルにオブジェクトを追加し、保存します。
const vacay_common = new Vacation_common({ name: "Honolulu", country: "USA" }); vacay_common.save((err, saveVacay) => { console.log("Saved: " + JSON.stringify(saveVacay)); });
ここで、Azure Portal に戻ると、
alldata
というコレクションが 1 つだけがあり、'Family' と 'VacationDestinations' 両方のデータが含まれていることがわかります。また、各オブジェクトには
__type
と呼ばれる別の属性があることも確認できます。これが 2 つの異なるオブジェクト モデルを区別するために使用されます。最後に、Azure Cosmos DB に格納されているデータを読み取ります。 モデルに基づいたデータのフィルター処理は Mongoose によって行われます。 そのため、データを読み取るときにそれ以外の処理を行う必要はありません。 モデル (この場合は
Family_common
)のみを指定すると、Mongoose が 'DiscriminatorKey' に基づいたフィルター処理を行います。Family_common.find({ 'children.gender' : "male"}, function(err, foundFamily){ foundFamily.forEach(fam => console.log("Found Family (using discriminator): " + JSON.stringify(fam))); });
説明からわかるように、Mongoose ディスクリミネーターは容易に使用できます。 そのため、Mongoose フレームワークを使用するアプリがある場合は、このチュートリアルを使用すると、それほど多くの変更を行わなくても Azure Cosmos DB の MongoDB 用 API を使用してアプリケーションを実行できます。
リソースをクリーンアップする
アプリと Azure Cosmos DB アカウントの使用を完了したら、それ以上料金がかからないように、作成した Azure リソースを削除できます。 リソースを削除するには、次の手順に従います。
Azure portal の検索バーで、「リソース グループ」を検索して選択します。
一覧から、このクイック スタートで作成したリソース グループを選択します。
リソース グループの [概要] ページで、[リソース グループの削除] を選択します。
次のウィンドウで、削除するリソース グループの名前を入力し、[削除] を選択します。
次のステップ
- Azure Cosmos DB の MongoDB 用 API と共に Studio 3T を使用する方法を学習します。
- Azure Cosmos DB の MongoDB 用 API と共に Robo 3T を使用する方法を学びます。
- Azure Cosmos DB の MongoDB 用 API を使用した MongoDB のサンプルを調査します。
- Azure Cosmos DB への移行のための容量計画を実行しようとしていますか? 容量計画のために、既存のデータベース クラスターに関する情報を使用できます。
- 既存のデータベース クラスター内の仮想コアとサーバーの数のみがわかっている場合は、仮想コア数または仮想 CPU 数を使用した要求ユニットの見積もりに関するページを参照してください
- 現在のデータベース ワークロードに対する通常の要求レートがわかっている場合は、Azure Cosmos DB Capacity Planner を使用した要求ユニットの見積もりに関するページを参照してください