sql >> データベース >  >> NoSQL >> MongoDB

マングースにスキーマとモデルの両方があるのはなぜですか?

    編集: これは多くの人にとって有用でしたが、コメントで述べられているように、それは理由ではなく「方法」に答えます。ありがたいことに、質問の理由は他の場所でも回答されており、この回答は別の質問に対するものです。これはしばらくの間コメントにリンクされていますが、多くの人が読んでいるときにそれほど遠くないかもしれないことを私は理解しています。

    多くの場合、このタイプの質問に答える最も簡単な方法は、例を使用することです。この場合、誰かが私のためにすでにそれを行っています:)

    こちらをご覧ください:

    http://rawberg.com/blog/nodejs/mongoose-orm-nested-models/

    編集: 元の投稿(コメントに記載されている)はもう存在しないようですので、以下に複製します。戻ってきた場合、または移動したばかりの場合は、お知らせください。

    マングースのモデル内でスキーマを使用する方法と、それを実行する理由について適切に説明します。また、スキーマが構造などに関するものであるときに、モデルを介してタスクをプッシュする方法も示します。

    元の投稿:

    モデル内にスキーマを埋め込む簡単な例から始めましょう。

    var TaskSchema = new Schema({
        name: String,
        priority: Number
    });
     
    TaskSchema.virtual('nameandpriority')
        .get( function () {
            return this.name + '(' + this.priority + ')';
        });
     
    TaskSchema.method('isHighPriority', function() {
        if(this.priority === 1) {
            return true;
        } else {
            return false;
        }
    }); 
     
    var ListSchema = new Schema({
        name: String,
        tasks: [TaskSchema]
    });
     
    mongoose.model('List', ListSchema);
     
    var List = mongoose.model('List');
     
    var sampleList = new List({name:'Sample List'});
    

    新しいTaskSchemaを作成しました タスクが持つ可能性のある基本情報を持つオブジェクト。タスクの名前と優先度を便利に組み合わせるために、Mongoose仮想属性が設定されています。ここではゲッターのみを指定しましたが、仮想セッターもサポートされています。

    isHighPriorityという簡単なタスクメソッドも定義しました メソッドがこの設定でどのように機能するかを示すため。

    ListSchema内 定義では、tasksがどのように行われるかに気付くでしょう キーは、TaskSchemaの配列を保持するように構成されています オブジェクト。 task キーはDocumentArrayのインスタンスになります これは、埋め込まれたMongoドキュメントを処理するための特別な方法を提供します。

    今のところ、私はListSchemaのみを渡しました mongoose.modelへのオブジェクト TaskSchemaを離れました アウト。技術的には、TaskSchemaをオンにする必要はありません。 独自のコレクションに保存しないため、正式なモデルに変換します。後で、それがどのように害を及ぼさないかを示します。特に、複数のファイルにまたがり始めたときに、すべてのモデルを同じように整理するのに役立ちます。

    Listを使用 モデルのセットアップでは、いくつかのタスクを追加してMongoに保存しましょう。

    var List = mongoose.model('List');
    var sampleList = new List({name:'Sample List'});
     
    sampleList.tasks.push(
        {name:'task one', priority:1}, 
        {name:'task two', priority:5}
    );
     
    sampleList.save(function(err) {
        if (err) {
            console.log('error adding new list');
            console.log(err);
        } else {
            console.log('new list successfully saved'); 
        }
    });
    

    Listのインスタンスのtasks属性 モデル(sampleList )は通常のJavaScript配列のように機能し、プッシュを使用して新しいタスクを追加できます。注意すべき重要なことは、tasksです。 通常のJavaScriptオブジェクトとして追加されます。微妙な違いで、すぐには直感的ではないかもしれません。

    新しいリストとタスクがmongoに保存されたことをMongoシェルから確認できます。

    db.lists.find()
    { "tasks" : [
        {
            "_id" : ObjectId("4dd1cbeed77909f507000002"),
            "priority" : 1,
            "name" : "task one"
        },
        {
            "_id" : ObjectId("4dd1cbeed77909f507000003"),
            "priority" : 5,
            "name" : "task two"
        }
    ], "_id" : ObjectId("4dd1cbeed77909f507000001"), "name" : "Sample List" }
    

    これで、ObjectIdを使用できます Sample Listをプルアップします タスクを繰り返します。

    List.findById('4dd1cbeed77909f507000001', function(err, list) {
        console.log(list.name + ' retrieved');
        list.tasks.forEach(function(task, index, array) {
            console.log(task.name);
            console.log(task.nameandpriority);
            console.log(task.isHighPriority());
        });
    });
    

    コードの最後のビットを実行すると、埋め込まれたドキュメントにメソッドisHighPriorityがないというエラーが表示されます。 。現在のバージョンのMongooseでは、埋め込みスキーマのメソッドに直接アクセスすることはできません。それを修正するためのオープンチケットがあり、Mongoose Googleグループに質問をした後、manimal45は今のところ使用するのに役立つ回避策を投稿しました。

    List.findById('4dd1cbeed77909f507000001', function(err, list) {
        console.log(list.name + ' retrieved');
        list.tasks.forEach(function(task, index, array) {
            console.log(task.name);
            console.log(task.nameandpriority);
            console.log(task._schema.methods.isHighPriority.apply(task));
        });
    });
    

    そのコードを実行すると、コマンドラインに次の出力が表示されます。

    Sample List retrieved
    task one
    task one (1)
    true
    task two
    task two (5)
    false
    

    その回避策を念頭に置いて、TaskSchemaを回してみましょう。 マングースモデルに。

    mongoose.model('Task', TaskSchema);
     
    var Task = mongoose.model('Task');
     
    var ListSchema = new Schema({
        name: String,
        tasks: [Task.schema]
    });
     
    mongoose.model('List', ListSchema);
     
    var List = mongoose.model('List');
    

    TaskSchema 定義は以前と同じなので省略しました。モデルに変換された後も、ドット表記を使用して、基になるスキーマオブジェクトにアクセスできます。

    新しいリストを作成し、その中に2つのタスクモデルインスタンスを埋め込みましょう。

    var demoList = new List({name:'Demo List'});
     
    var taskThree = new Task({name:'task three', priority:10});
    var taskFour = new Task({name:'task four', priority:11});
     
    demoList.tasks.push(taskThree.toObject(), taskFour.toObject());
     
    demoList.save(function(err) {
        if (err) {
            console.log('error adding new list');
            console.log(err);
        } else {
            console.log('new list successfully saved'); 
        }
    });
    

    タスクモデルインスタンスをリストに埋め込むため、toObjectを呼び出します。 List.tasksがデータをプレーンなJavaScriptオブジェクトに変換するためにそれらを使用します DocumentArray 期待しています。この方法でモデルインスタンスを保存すると、埋め込まれたドキュメントにObjectIdsが含まれます。 。

    完全なコード例は要点として利用できます。うまくいけば、これらの回避策は、マングースが発展し続けるにつれて、物事をスムーズにするのに役立つでしょう。私はまだMongooseとMongoDBにかなり慣れていないので、コメントでより良い解決策とヒントを自由に共有してください。ハッピーデータモデリング!



    1. MongoDBジャーナリングを有効にする必要がありますか?

    2. 何を使うべきですか? Socket.ioルームまたはRedispub-sub?

    3. Mongodbでタイムゾーン設定を使用してクエリを実行する方法

    4. sidekiqワーカーがperform_asyncで実行されているかどうかを確認する方法を説明します