32

Mongoose.jsを使用していますが、3レベルの階層ドキュメントの問題を解決できません。

それを行うには2つの方法があります。

最初に-参照なし。

C = new Schema({
    'title': String,
});

B = new Schema({
    'title': String,
    'c': [C]
});

A = new Schema({
    'title': String,
    'b': [B]
});

Cレコードを表示する必要があります。Cの_idだけを知っているのに、どうすればそれを入力/検索できますか?

私は使ってみました:

A.findOne({'b.c._id': req.params.c_id}, function(err, a){
    console.log(a);
});

しかし、returnetから必要なオブジェクトのみを取得する方法がわかりません。

refsを使用する場合の2番目:

C = new Schema({
    'title': String,
});

B = new Schema({
    'title': String,
    'c': [{ type: Schema.Types.ObjectId, ref: 'C' }]
});

A = new Schema({
    'title': String,
    'b': [{ type: Schema.Types.ObjectId, ref: 'B' }]
});

すべてのB、Cレコードにデータを入力して、階層を取得するにはどうすればよいですか?

私はこのようなものを使おうとしました:

A
.find({})
.populate('b')
.populate('b.c')
.exec(function(err, a){
    a.forEach(function(single_a){
        console.log('- ' + single_a.title);
        single_a.b.forEach(function(single_b){
            console.log('-- ' + single_b.title);
            single_b.c.forEach(function(single_c){
                console.log('--- ' + single_c.title);
            });
        });
    });
});

ただし、single_c.titleに対して未定義を返します。私はそれを投入する方法がありますか?

ありがとう。

4

4 に答える 4

43

Mongoose 3.6以降、クエリに関連ドキュメントを再帰的に入力する機能が追加されました。これを行う方法の例を次に示します。

 UserList.findById(listId)
         .populate('refUserListItems')
         .exec(function(err, doc){
             UserListItem.populate(doc.refUserListItems, {path:'refSuggestion'},
                   function(err, data){
                        console.log("User List data: %j", doc);
                        cb(null, doc);
                   }
             );     
          });           

この場合、「refUserListItems」内のIDの配列にそれらの参照ドキュメントを入力しています。次に、クエリの結果は、入力したい元の入力済みドキュメントのフィールドを参照する別の入力クエリに渡されます-'refSuggestion'。

2番目の(内部)ポピュレートに注意してください-これは魔法が起こる場所です。必要な方法でグラフを作成するまで、これらのデータをネストし、さらに多くのドキュメントに追加することができます。

これがどのように機能しているかを理解するのに少し時間がかかりますが、それを実行するのであれば、それは理にかなっています。

于 2013-08-14T15:11:38.880 に答える
34

Mongoose 4では、このようにマルチレベルにデータを入力できます(異なるデータベースやインスタンスでも)

A
.find({})
.populate({
  path: 'b', 
  model: 'B',
  populate: {
    path: 'c',
    model: 'C'
  }
})
.exec(function(err, a){});
于 2015-12-23T22:22:01.910 に答える
31

Mongoose 4では、複数のレベルにわたってドキュメントを設定できます。

ユーザーの友達を追跡するユーザースキーマがあるとします。

var userSchema = new Schema({
  name: String,
  friends: [{ type: ObjectId, ref: 'User' }]
});

まずpopulate()、ユーザーの友達のリストを取得できます。しかし、ユーザーの友達の友達も必要な場合はどうでしょうか。その場合、すべてのユーザーの友達の配列にpopulateデータを入力するようにmongooseに指示するオプションを指定できます。friends

User.
  findOne({ name: 'Val' }).
  populate({
    path: 'friends',
    // Get friends of friends - populate the 'friends' array for every friend
    populate: { path: 'friends' }
  });

取得元:http ://mongoosejs.com/docs/populate.html#deep-populate

于 2012-10-31T17:44:31.463 に答える
5

私はこれに遅れていますが、深いモデルの作成を非常に簡単に実行できるようにするMongooseプラグインを作成しました。あなたの例では、これを実行してデータを入力し、次のようにすることができbますc

A.find({}, function (err, docs) {
  A.deepPopulate(docs, 'b.c', cb)
}

次のように、入力されたパスごとにMongooseの入力オプションを指定することもできます。

A.deepPopulate(docs, 'b.c', {
  b: { 
    select: 'name'
  }
}, cb)

詳細については、プラグインのドキュメントを確認してください。

于 2014-12-10T19:44:06.640 に答える