私はnode.jsとmongodbを学習中です。多くのチュートリアルの推奨により、mongoose を利用して mongo とのやり取りを支援しています。問題を複雑にするために、私は重要な RDMS のバックグラウンドを持っており、SQL レンズを通して mongodb を見たいという私の心の欲求と戦うために最善を尽くしています。
現在、サブドキュメントのクエリの概念に苦労しています。サブドキュメントのプロパティに基づいて親ドキュメントをクエリする方法はわかりましたが、子ドキュメントを直接クエリしてすべての親ドキュメント (タイプに関係なく) をクエリする方法がわかりません。説明するために、次の不自然なスキーマの例があります。
// subdocument
var CategorySchema = new Schema({
name: { type: String, required: true }
});
var IpSchema = new Schema({
ip_address: { type: String, required: true, index: true }
,categories: [CategorySchema]
});
var DomainSchema = new Schema({
domain_name: { type: String, required: true, index: true }
,categories: [CategorySchema]
});
var ip = mongoose.model('Ip', IpSchema);
var domain = mongoose.model('Domain', DomainSchema);
var category = mongoose.model('Category', CategorySchema);
上記のスキーマは、保存された各ドメインと IP ドキュメントにカテゴリのサブドキュメント配列を埋め込みます。カテゴリ名に基づいてドメインと IP を個別に取得することは簡単ですが、特定のカテゴリに関連付けられたすべてのドメインと IP を一度に取得することは困難です。以下のコードは、私がこれを信じる理由の概要を示しています。
category.find(function (err, tcs) {
console.log(tcs); // contains an empty set because no categories stored here
});
ip.find({ 'categories.name' : req.params.category }, function(err, ips) {
console.log(ips); // contains all parent documents w/ subdocument name
});
domain.find({ 'categories.name' : req.params.category }, function(err, ips) {
console.log(ips); // contains all parent documents w/ subdocument name
});
これで、上記のクエリの結果を組み合わせることができましたが、これは脆弱な可能性があるように思われます (ますます多くのドキュメントでカテゴリを再利用すると仮定すると)。カテゴリを保存してから、カテゴリ ID を介して参照を埋め込む必要がありますか? 読み取りを最適化するために書き込みを行うと、チャーンが増加するようです。残念ながら、私の Googlefu では、タグ付けスキームのチュートリアルやベスト プラクティスを見つけることができませんでした。また、私が物事を過度に複雑にしている可能性もあります。
共有サブドキュメントに基づいて異なる親ドキュメントを取得する最良の方法は何ですか?