データベース参照
MongoDB の多くのユースケースでは、単一のドキュメント内に関連データが保存される非正規化データモデルが最適です。 ただし、関連情報を別個のドキュメント(通常は別個のコレクションまたはデータベース)に保存する方が合理的なケースもあります。
重要
パイプライン ステージ $lookup
を使用して、同じデータベース内の非シャードコレクションへの左外部結合を実行できます。
また、パイプライン ステージ $graphLookup
を使用して、シャーディングされていないコレクションを結合して再帰検索を実行することもできます。
このページでは、パイプライン ステージ $lookup
および$graphLookup
に先行する代替手順について説明します。
下記の環境でホストされている配置向けにデータベース参照を作成できます。
MongoDB Atlas はクラウドでの MongoDB 配置のためのフルマネージド サービスです
MongoDB Enterprise: サブスクリプションベースの自己管理型 MongoDB バージョン
MongoDB Community: ソースが利用可能で、無料で使用できる自己管理型の MongoDB のバージョン
MongoDB アプリケーションは、ドキュメントの関連付けのために下記の 2 つの方法のいずれかを使用します。
手動参照では、あるドキュメントの
_id
フィールドを別のドキュメントに参照として保存します。アプリケーションにより 2 つ目のクエリが実行され、関連データが返されます。これらの参照は簡単で、ほとんどのユースケースにおいて十分です。DBRefは、最初のドキュメントの
_id
フィールド、コレクション名、および任意でそのデータベース名、およびその他のフィールドの値を使用して、あるドキュメントから別のドキュメントへの参照です。 DBRef を使用すると、複数のコレクションやデータベースに保存されているドキュメントをより簡単に参照できます。
DBRefs を解決するには、参照先のドキュメントが返されるよう、アプリケーションで追加のクエリが実行されなければなりません。一部の MongoDB ドライバーでは、DBRef をドキュメントの形で解決できるようにするヘルパー メソッドが提供されていますが、これは自動的に実行されることはありません。
DBRef は、ドキュメント間の関係を表す共通の形式とタイプを提供します。さらに DBRef 形式は、データベースで複数のフレームワークやツールとのインタラクションが必要な場合に、ドキュメント間のリンクを表現する共通のセマンティクスも提供します。
DBRefs を使用するやむを得ない理由がない限り、代わりに手動参照を使用してください。
手動参照
バックグラウンド
手動参照とは、あるドキュメントの _id
フィールドを別のドキュメントに含める手法です。その後、アプリケーションは必要に応じて 2 番目のクエリを発行して、参照されたフィールドを解決できます。
MongoDB Atlas UIでの手動参照の作成
MongoDB Atlas の UI で手動参照を作成するには、次の手順に従います。
MongoDB Atlas UIで、プロジェクトのClusters ページに移動します。
まだ表示されていない場合は、希望するプロジェクトを含む組織を選択しますナビゲーション バーのOrganizationsメニュー
まだ表示されていない場合は、ナビゲーション バーの Projects メニューからプロジェクトを選択します。
まだ表示されていない場合は、サイドバーの [ Clusters ] をクリックします。
[ Clusters (クラスター) ] ページが表示されます。
people
のエントリを参照するドキュメントをplaces
コレクションに追加します。
左側のナビゲーション ペインで別のコレクションを選択します。この例では
people
コレクションを参照します。[Insert Document] をクリックします。
JSON ビュー アイコン ( {{}} ) をクリックします。
以下のデータをドキュメントに貼り付けます。
{ "_id": { "$oid": "651aebeb70299b120736f443" }, "name": "Erin", "places_id": "651aea5870299b120736f442" "url": "bc.example.net/Erin" } [Insert] をクリックします。
クエリが
people
コレクションのドキュメントを返す際に、必要であれば、places_id
フィールドで参照されるドキュメントでのplaces
コレクションからのクエリ結果をフィルタリングできます。MongoDB Atlas でクエリを実行する方法の詳細については、MongoDB Atlas ドキュメントのドキュメントの表示、フィルター処理、並べ替えを参照してください。
ターミナルでの手動参照の作成
以下のように、1 つ目のドキュメントの _id
フィールドを2 つ目のドキュメントの参照として使用して、2つのドキュメントを挿入する操作を考えてみましょう。
original_id = ObjectId() db.places.insertOne({ "_id": original_id, "name": "Broadway Center", "url": "bc.example.net" }) db.people.insertOne({ "name": "Erin", "places_id": original_id, "url": "bc.example.net/Erin" })
次に、クエリが people
コレクションからドキュメントを返す際に、必要に応じて places
コレクションの places_id
フィールドで参照されたドキュメントに対して 2 回目のクエリを実行できます。
使用
2 つのドキュメントの関係の保存が必要なほとんどの場合に、手動参照を使用します。参照は簡単に作成でき、アプリケーションが必要に応じて参照を解決できます。
手動リンクの唯一の制約は、これらの参照がデータベース名とコレクション名を伝達しないことです。1 つのコレクション内のドキュメントが、複数のコレクションのドキュメントに関連付けられている場合には、 DBRef の使用を検討する必要があるかもしれません。
DBRefs
バックグラウンド
DBRef は、特定の参照タイプというよりは、むしろドキュメントを表現するための規則です。DBRef には _id
フィールドの値に加え、コレクション名、場合によってはデータベース名が含まれます。
オプションとして、DBRef には任意の数の他のフィールドを含めることができます。追加のフィールド名は、サーバーバージョンによって課せられているフィールド名の規則に従う必要があります。
形式
DBRef には、次のフィールドがあります。
$ref
$ref
フィールドは、参照先のドキュメントが存在するコレクションの名前を保持します。
$id
$id
フィールドは、参照先のドキュメントの_id
フィールドの値を含みます。
$db
任意。
参照先のドキュメントが存在するデータベースの名前を含みます。
例
DBRef ドキュメントは下記のドキュメントに近似します。
{ "$ref" : <value>, "$id" : <value>, "$db" : <value> }
creator
フィールドに DBRef を格納したコレクションのドキュメントを例にとります。
{ "_id" : ObjectId("5126bbf64aed4daf9e2ab771"), // .. application fields "creator" : { "$ref" : "creators", "$id" : ObjectId("5126bc054aed4daf9e2ab772"), "$db" : "users", "extraField" : "anything" } }
この例の DBRef は、users
データベースの creators
コレクションにある、_id
フィールドに ObjectId("5126bc054aed4daf9e2ab772")
を持つドキュメントを指しています。さらに任意のフィールドも含まれています。
注意
DBRef 内のフィールドの順序は重要です。DBRef を使用する場合は必ず上記の順序に従う必要があります。
DBRefs のドライバー サポート
ドライバー | DBRef のサポート | ノート |
---|---|---|
C | サポートなし | 参照を手動で走査できます。 |
C++ | サポートなし | 参照を手動で走査できます。 |
C# | サポートあり | 詳細についてはC# ドライバーのページを参照してください。 |
Go | サポートなし | 参照を手動で走査できます。 |
Haskell | サポートなし | 参照を手動で走査できます。 |
Java | サポートあり | 詳細についてはJava ドライバーのページを参照してください。 |
Node.js | サポートあり | 詳細については、 Node.js ドライバーのページを参照してください。 |
Perl | サポートあり | 詳細についてはPerl ドライバーのページを参照してください。 |
PHP | サポートなし | 参照を手動で走査できます。 |
Python | サポートあり | 詳細についてはPyMongo ドライバーのページを参照してください。 |
Ruby | サポートあり | 詳細についてはRuby ドライバーのページを参照してください。 |
Scala | サポートなし | 参照を手動で走査できます。 |
使用
2 つ以上の関連ドキュメントを接続するには、ほとんどの場合、手動参照 メソッドを使用します。ただし、複数のコレクションからドキュメントを参照する必要がある場合は、DBRefs の使用を検討してください。