2016-10-07 19 views
7

2つの収集、タグ、および人がいます。

タグモデル:

{ 
    en: String, 
    sv: String 
} 

人モデル:

{ 
    name: String, 
    projects: [ 
    title: String, 
    tags: [ 
     { 
     type: Schema.ObjectId, 
     ref: 'tag' 
     } 
    ] 
    ] 

} 

私は人のモデルで使用されているすべてのタグを返すクエリをしたいです。すべての文書。

var query = mongoose.model('tag').find({...}); 

ようSometehingまたは私は何とかこれに集約アプローチを使用する必要がありますか?

+0

$lookup演算子をサポートしていない3.0として集計の結果を移入するのですか? 人に関係なく、すべてのタグを一覧表示する場合は、タグコレクションを直接照会することができます。 –

+0

私はアプリケーション全体でタグを使いたいです。すべての人物のproject.tagsに存在するすべてのタグ。 – Per

答えて

19

あなたが例えば「MongoDBは」または「ノードJS」は任意のタグを持つすべての人のために検索したい場合は、あなたは、

var query = mongoose.model("person").find({ "name": "foo" }).populate("projects.tags"); 

ようpopulate()機能を利用することができpopulate()機能過負荷でのクエリオプションを含めることができます。

var query = mongoose.model("person").find({ "name": "foo" }).populate({ 
    "path": "projects.tags", 
    "match": { "en": { "$in": ["MongoDB", "Node JS"] } } 
}); 

あなたはすべてのタグは、すべての人のために"project.tags"に存在する場合は、アグリゲーション・フレームワークが道のりです。その後、フィルタリングする最初のステップとして$matchパイプラインを適用

mongoose.model('person').aggregate([ 
    { "$unwind": "$projects" }, 
    { "$unwind": "$projects.tags" }, 
    { 
     "$lookup": { 
      "from": "tags", 
      "localField": "projects.tags", 
      "foreignField": "_id", 
      "as": "resultingTagsArray" 
     } 
    }, 
    { "$unwind": "$resultingTagsArray" }, 
    { 
     "$group": { 
      "_id": null, 
      "allTags": { "$addToSet": "$resultingTagsArray" }, 
      "count": { "$sum": 1 } 
     } 
    } 
]).exec(function(err, results){ 
    console.log(results); 
}) 

いかなる特定の人のために:人のコレクションで、このパイプラインを実行することを検討し、タグのコレクションに参加し、左を行うために$lookup演算子を使用していますドキュメント:

mongoose.model('person').aggregate([ 
    { "$match": { "name": "foo" } }, 
    { "$unwind": "$projects" }, 
    { "$unwind": "$projects.tags" }, 
    { 
     "$lookup": { 
      "from": "tags", 
      "localField": "projects.tags", 
      "foreignField": "_id", 
      "as": "resultingTagsArray" 
     } 
    }, 
    { "$unwind": "$resultingTagsArray" }, 
    { 
     "$group": { 
      "_id": null, 
      "allTags": { "$addToSet": "$resultingTagsArray" }, 
      "count": { "$sum": 1 } 
     } 
    } 
]).exec(function(err, results){ 
    console.log(results); 
}) 

別の回避策を使用すると、MongoDBのバージョンを使用している場合> = 2.6または< =あなたが特定の人のために全体のアプリケーションのすべてのタグまたはすべてのタグをしたい

mongoose.model('person').aggregate([ 
    { "$unwind": "$projects" }, 
    { "$unwind": "$projects.tags" },  
    { 
     "$group": { 
      "_id": null, 
      "allTags": { "$addToSet": "$projects.tags" } 
     } 
    } 
], function(err, result) { 
    mongoose.model('person') 
    .populate(result, { "path": "allTags" }, function(err, results) { 
     if (err) throw err; 
     console.log(JSON.stringify(results, undefined, 4)); 
    }); 
}); 
+0

申し訳ありません!私は私の記事で間違いを犯しました。プロジェクトはオブジェクトではありません。それは配列です。私は質問を更新しました。もう一度見ていただけますか? – Per

+0

これは、更新された回答のように、別の '' "unwind": "$ projects"} 'パイプラインの前に置くことで修正できます。 – chridam

+1

非常に強力なもの。ある日、この集約フレームワークを学ばなければならない。どうも! – Per

1

MongoDbバージョン3.2を使用している場合は、左外部結合を実行する$lookupを使用できます。いずれかの特定のユーザー文書の場合

関連する問題