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

単一のスキーマ配列内の複数のスキーマ参照-マングース

    ここで探しているのはマングースの.discriminator() 方法。これにより、基本的に、同じコレクションに異なるタイプのオブジェクトを格納できますが、それらを区別可能なファーストクラスのオブジェクトとして持つことができます。

    ここでの「同じコレクション」の原則は、.populate()の方法にとって重要であることに注意してください。 動作し、含まれているモデルの参照の定義。とにかく、実際には参照用に「1つの」モデルしかポイントできないためですが、1つのモデルを同じ数だけ表示できる魔法が他にもあります。

    リストの例:

    var util = require('util'),
        async = require('async'),
        mongoose = require('mongoose'),
        Schema = mongoose.Schema;
    
    mongoose.connect('mongodb://localhost/gunshow');
    
    //mongoose.set("debug",true);
    
    var scenarioSchema = new Schema({
      "name": String,
      "guns": [{ "type": Schema.Types.ObjectId, "ref": "Gun" }]
    });
    
    function BaseSchema() {
      Schema.apply(this, arguments);
    
      // Common Gun stuff
      this.add({
        "createdAt": { "type": Date, "default": Date.now }
      });
    }
    
    util.inherits(BaseSchema, Schema);
    
    var gunSchema = new BaseSchema();
    
    var ak47Schema = new BaseSchema({
      // Ak74 stuff
    });
    
    ak47Schema.methods.shoot = function() {
      return "Crack!Crack";
    };
    
    var m16Schema = new BaseSchema({
      // M16 Stuff
    });
    
    m16Schema.methods.shoot = function() {
      return "Blam!!"
    };
    
    
    var Scenario = mongoose.model("Scenario", scenarioSchema);
    
    var Gun = mongoose.model("Gun", gunSchema );
    var Ak47 = Gun.discriminator("Ak47", ak47Schema );
    var M16 = Gun.discriminator("M16", m16Schema );
    
    
    async.series(
      [
        // Cleanup
        function(callback) {
          async.each([Scenario,Gun],function(model,callback) {
            model.remove({},callback);
          },callback);
        },
    
        // Add some guns and add to scenario
        function(callback) {
          async.waterfall(
            [
              function(callback) {
                async.map([Ak47,M16],function(gun,callback) {
                  gun.create({},callback);
                },callback);
              },
              function(guns,callback) {
                Scenario.create({
                  "name": "Test",
                  "guns": guns
                },callback);
              }
            ],
            callback
          );
        },
    
        // Get populated scenario
        function(callback) {
          Scenario.findOne().populate("guns").exec(function(err,data) {
    
            console.log("Populated:\n%s",JSON.stringify(data,undefined,2));
    
            // Shoot each gun for fun!
            data.guns.forEach(function(gun) {
              console.log("%s says %s",gun.__t,gun.shoot());
            });
    
            callback(err);
          });
        },
    
        // Show the Guns collection
        function(callback) {
          Gun.find().exec(function(err,guns) {
            console.log("Guns:\n%s", JSON.stringify(guns,undefined,2));
            callback(err);
          });
        },
    
        // Show magic filtering
        function(callback) {
          Ak47.find().exec(function(err,ak47) {
            console.log("Magic!:\n%s", JSON.stringify(ak47,undefined,2));
            callback(err);
          });
        }
      ],
      function(err) {
        if (err) throw err;
        mongoose.disconnect();
      }
    );
    

    そして出力

    Populated:
    {
      "_id": "56c508069d16fab84ead921d",
      "name": "Test",
      "__v": 0,
      "guns": [
        {
          "_id": "56c508069d16fab84ead921b",
          "__v": 0,
          "__t": "Ak47",
          "createdAt": "2016-02-17T23:53:42.853Z"
        },
        {
          "_id": "56c508069d16fab84ead921c",
          "__v": 0,
          "__t": "M16",
          "createdAt": "2016-02-17T23:53:42.862Z"
        }
      ]
    }
    Ak47 says Crack!Crack
    M16 says Blam!!
    Guns:
    [
      {
        "_id": "56c508069d16fab84ead921b",
        "__v": 0,
        "__t": "Ak47",
        "createdAt": "2016-02-17T23:53:42.853Z"
      },
      {
        "_id": "56c508069d16fab84ead921c",
        "__v": 0,
        "__t": "M16",
        "createdAt": "2016-02-17T23:53:42.862Z"
      }
    ]
    Magic!:
    [
      {
        "_id": "56c508069d16fab84ead921b",
        "__v": 0,
        "__t": "Ak47",
        "createdAt": "2016-02-17T23:53:42.853Z"
      }
    ]
    

    mongoose.set("debug",true)のコメントを解除することもできます リストの行に、マングースが実際にどのように呼び出しを構築しているかを確認します。

    つまり、これが示すのは、さまざまなスキーマをさまざまなファーストクラスオブジェクトに適用でき、実際のオブジェクトと同じようにさまざまなメソッドをアタッチした場合でも適用できるということです。マングースはこれらすべてをモデルが添付された「銃」コレクションに保存しており、識別器によって参照されるすべての「タイプ」が含まれます。

    var Gun = mongoose.model("Gun", gunSchema );
    var Ak47 = Gun.discriminator("Ak47", ak47Schema );
    var M16 = Gun.discriminator("M16", m16Schema );
    

    ただし、それぞれの異なる「タイプ」は、特別な方法で独自のモデルで参照されます。つまり、マングースがオブジェクトを保存して読み取るときに、特別な__tがあることがわかります。 適用する「モデル」、つまり添付されたスキーマを指示するフィールド。

    一例として、.shoot()を呼び出します。 モデル/スキーマごとに異なる方法で定義されたメソッド。また、Ak47なので、クエリやその他の操作のモデルとしてそれぞれを単独で使用することもできます。 __tを自動的に適用します すべてのクエリ/更新の値。

    したがって、ストレージは1つのコレクションに含まれていますが、多くのコレクションのように見える場合がありますが、他の便利な操作のためにそれらをまとめておくという利点もあります。これが、あなたが探している種類の「ポリモーフィズム」を適用する方法です。




    1. MongoDBで配列の順序を変更するにはどうすればよいですか?

    2. 制限を使用するときにMongoDBでドキュメントの総数を取得する

    3. node.jsとmongodbで登録とログインフォームを作成する

    4. Node.jsを使用してMongoDBデータベースへのSSHトンネリング接続を確立する方法