次のようなレコードを持つウィジェットコレクションがあります。
{ "_id" : ObjectId("55a6abe193819c033d4d755a"), "name" : "widget1"}
{ "_id" : ObjectId("55a6abe193819c033d4d755a"), "name" : "widget2", "loc" : ObjectId("55a69475da314d9984fc6201") }
次のようなLocationsコレクションもあります。
{ "_id" : ObjectId("55a69475da314d9984fc6201"), "abbrev" : "CAN", "description" : "Canada" }
{ "_id" : ObjectId("55a6948eda314d9984fc6202"), "abbrev" : "USA", "description" : "United States" }
{ "_id" : ObjectId("55a69496da314d9984fc6203"), "abbrev" : "MEX", "description" : "Mexico" }
Objectidを使用して、カナダにあるすべてのウィジェットを検索したい場合、私はこれを実行できることを知っています。
> db.widgets.find( { loc: ObjectId("55a69475da314d9984fc6201")})
{ "_id" : ObjectId("55a6abe193819c033d4d755a"), "name" : "widget2", "loc" : ObjectId("55a69475da314d9984fc6201") }
しかし、objectidではなく省略形または説明を使用して場所を検索する場合はどうなりますか?どうすればいいですか?
関連データを使用して2つのコレクションをクエリするには、一般的なアプローチ(MongoDB 3.0と同様)は、2番目の_id
クエリで使用できる最初のコレクションから一致する$in
値のリストを見つけることです。
mongo
シェルを使用した例を次に示します。
// Find _ids for matching locations based on some criteria (eg. "abbrev")
var matches = db.locations.find({ "abbrev": "CAN"}, { _id: 1 })
// Transform matching _id values into an array
var locs = [];
matches.forEach(function(match) { locs.Push(match._id) });
// Look for widgets matching the location criteria
db.widgets.find({"loc": {$in : locs} } )
使用しているドライバーやフレームワークによっては、関連データの入力を容易にするヘルパー関数が存在する場合があります。現在、サーバー側の結合はサポートされていないため、これらのヘルパー関数は最終的に複数のクエリになります。
ヘルパーを含むフレームワークのいくつかの例(包括的なリストを意図したものではありません):
mongo
インタラクティブシェルの実験的なアドイン私は、現在、データを入力するためのサーバー側のサポートがないと言ったかもしれません。 MongoDB 3.1.x開発サイクルのアグリゲーションフレームワークには、実際に新しい$lookup
演算子が追加されています(最終的には、MongoDB 3.2の最終的な本番リリースシリーズになります)。詳細については、MongoDB Jira課題トラッカーの SERVER-19095 を参照してください。