web-dev-qa-db-ja.com

mongoDB:オブジェクト参照を持つドキュメントのクエリ

次のようなレコードを持つウィジェットコレクションがあります。

{ "_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ではなく省略形または説明を使用して場所を検索する場合はどうなりますか?どうすればいいですか?

3
dot

関連データを使用して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} } )

使用しているドライバーやフレームワークによっては、関連データの入力を容易にするヘルパー関数が存在する場合があります。現在、サーバー側の結合はサポートされていないため、これらのヘルパー関数は最終的に複数のクエリになります。

ヘルパーを含むフレームワークのいくつかの例(包括的なリストを意図したものではありません):

  • MongooseJS:クエリの母集団 :宣言型スキーマと関係のクエリの母集団を含むNode.jsオブジェクトドキュメントモデル(ODM)フレームワーク
  • Mongoid:Relations :Ruby宣言型スキーマを含むODMと関係のクエリ母集団
  • mongo-views :クエリ可能なビュー/仮想コレクションのサポートを追加するmongoインタラクティブシェルの実験的なアドイン

私は、現在、データを入力するためのサーバー側のサポートがないと言ったかもしれません。 MongoDB 3.1.x開発サイクルのアグリゲーションフレームワークには、実際に新しい$lookup演算子が追加されています(最終的には、MongoDB 3.2の最終的な本番リリースシリーズになります)。詳細については、MongoDB Jira課題トラッカーの SERVER-19095 を参照してください。

6
Stennie