web-dev-qa-db-ja.com

スキーマ内のマングーススキーマ

スキーマを別のスキーマに追加するにはどうすればよいですか?これは有効ではないようです:

var UserSchema = new Schema({
    name        : String,
    app_key     : String,
    app_secret  : String
})



var TaskSchema = new Schema({
    name            : String,
    lastPerformed   : Date,
    folder          : String,
    user            : UserSchema
})

私はウェブサイトをチェックしましたが、それは配列に対して宣言する方法を示していますが、単一に対しては宣言していません。

ありがとう

28
0xSina

これを行うにはいくつかの方法があります。最も簡単なのはこれだけです:

var TaskSchema = new Schema({
    name            : String,
    lastPerformed   : Date,
    folder          : String,
    user            : Schema.ObjectId
});

次に、必要に応じて、アプリがそのIDを書き込み、それをクエリで使用して「関連」データをフェッチすることを確認する必要があります。

これは、ユーザーIDでタスクを検索する場合は問題ありませんが、タスクIDでユーザーをクエリする場合はさらに面倒です。

// Get tasks with user id
Task.find({user: user_id}, function(err, tasks) {...});

// Get user from task id
Task.findById(id, function(err, task) {
  User.findById(task.user, function(err, user) {
    // do stuff with user
  }
}

別の方法は、Mongooseの populate 機能を利用してクエリを簡略化することです。これを取得するには、次のようにします。

var UserSchema = new Schema({
    name        : String,
    app_key     : String,
    app_secret  : String,
    tasks       : [{type: Schema.ObjectId, ref: 'Task'}] // assuming you name your model Task
});

var TaskSchema = new Schema({
    name            : String,
    lastPerformed   : Date,
    folder          : String,
    user            : {type: Schema.ObjectId, ref: 'User'} // assuming you name your model User
});

これにより、タスクの配列を含むすべてのユーザーのクエリは次のようになります。

User.find({}).populate('tasks').run(function(err, users) {
  // do something
});

もちろん、これは両方の場所でIDを維持することを意味します。それが気になる場合は、最初の方法に固執し、より複雑な(ただし十分に単純な)クエリの記述に慣れるのが最善の方法です。

36
glortho

このシンプルなソリューションはどうですか?

var TaskSchema = new Schema({
    name            : String,
    lastPerformed   : Date,
    folder          : String,
    user            : {
        name        : String,
        app_key     : String,
        app_secret  : String
    }
 })
10
Jamund Ferguson

バージョン4.2.0以降、mongooseは単一のサブドキュメントをサポートしています。

the docs から:

var childSchema = new Schema({ name: 'string' });

var parentSchema = new Schema({
  // Array of subdocuments
  children: [childSchema],
  // Single nested subdocuments. Caveat: single nested subdocs only work
  // in mongoose >= 4.2.0
  child: childSchema
});
1
Ben Henderson