麻烦与Mongoose和Schema.Types.Mixed

时间:2014-07-10 11:05:26

标签: javascript node.js mongodb mongoose

我试图拥有一个完全混合的模型但不能真正让它发挥作用,这里是完整的javascript:

var mongoose = require('mongoose'),
    Schema = mongoose.Schema,
    async = require('async');

mongoose.connect('mongodb://localhost/whatever');

var SomeDocument = mongoose.model('SomeDocument', new Schema({ any: Schema.Types.Mixed }) );

var AnotherDocument = mongoose.model('AnotherDocument', new Schema({ any: Schema.Types.Mixed }, { strict: false } ) );

async.waterfall([
    function(cb) {
        var saveThis = {lets: "have", some: "fun"};
        console.log("Trying to save:", saveThis);
        SomeDocument.create(saveThis, function(err, savedDoc) {
            console.log("Created SomeDocument: ", savedDoc);
            cb(null, savedDoc._id.toString());
        });
    },
    function(id, cb) {
        SomeDocument.findOne({_id: id}, function(err, someDoc) {
            console.log("Found SomeDocument", someDoc);
            cb(null);
        });
    },
    function(cb) {
        AnotherDocument.create({maybe: "now", we: "can", have: "fun"}, function(err, savedDoc) {
            console.log("Created AnotherDocument", savedDoc);
            cb(null, savedDoc._id.toString());
        });
    },
    function(id, cb) {
        AnotherDocument.findOne({_id: id}, function(err, anotherDoc) {
            console.log("Found AnotherDocument", anotherDoc);
            console.log("Seems like progress, but what about: ", anotherDoc._id, anotherDoc.maybe, anotherDoc.we, anotherDoc.have);
            console.log("need moar brains");
            cb(null);
        });
    },
    function(cb) {
        mongoose.disconnect();
    }
]);

SomeDocument或AnotherDocument都没有像我期望的那样工作。第一个甚至不保存额外的字段,另一个不会让我读取对象属性...

以上代码输出:

$ node test.js
Trying to save: { lets: 'have', some: 'fun' }
Created SomeDocument:  { __v: 0, _id: 53be7279c90a4def0d000001 }
Found SomeDocument { _id: 53be7279c90a4def0d000001, __v: 0 }
Created AnotherDocument { __v: 0,
  maybe: 'now',
  we: 'can',
  have: 'fun',
  _id: 53be7279c90a4def0d000002 }
Found AnotherDocument { maybe: 'now',
  we: 'can',
  have: 'fun',
  _id: 53be7279c90a4def0d000002,
  __v: 0 }
Seems like progress, but what about:  53be7279c90a4def0d000002 undefined undefined undefined
need moar brains

这是一个错误还是我错过了什么?

主要问题是即使console.log实际上似乎在保存时输出文档,当我尝试访问anotherDoc.maybe时 - 突然undefined

版本:

mongoose@3.6.20 node_modules/mongoose
├── regexp-clone@0.0.1
├── sliced@0.0.5
├── muri@0.3.1
├── hooks@0.2.1
├── mpath@0.1.1
├── ms@0.1.0
├── mpromise@0.2.1 (sliced@0.0.4)
└── mongodb@1.3.19 (kerberos@0.0.3, bson@0.2.2)

$ node -v
v0.10.25

$ uname -a
Linux deployment 3.11.0-24-generic #42-Ubuntu SMP Fri Jul 4 21:19:31 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

1 个答案:

答案 0 :(得分:1)

你对“瀑布”的使用实际上是不正确的。如果您希望这些变量在最终操作中可见,那么您需要通过所有这些变量。因此,每个连续的回调都需要“传递”您收到的变量。这些不仅仅是“自动降落”到最低级别。

虽然这里有真正的问题。

如果您只想要一个完全无模式的方法,那么只需使用{"strict": false }

var docSchema = new Schema({},{ "strict": false });
var Document = mongoose.model( "Document", documentSchema );

这不限制字段,基本上一切都有效。 “混合”实际上仅适用于字段和类型可能不同的字段定义。

在这种情况下保留默认的_id作为ObjectId,但是你似乎没有覆盖它。


再次查看问题,"strict": false被遗漏from the documentation。其他“已定义”字段的访问器不存在。您需要使用通用.set().get()

var async = require("async"),
    mongoose = require("mongoose"),
    Schema = mongoose.Schema;

mongoose.connect('mongodb://localhost/test');


var mixSchema = new Schema({},{ "strict": false });

var Mix = mongoose.model( "Mix", mixSchema );

var report = function(label,data) {
  console.log(
    "%s\n%s\n",
    label,
    JSON.stringify( data, undefined, 4 )
  );
};

async.waterfall([

  function(callback) {
    Mix.create({ "lets": "have", "some": "fun" },function(err,doc) {
      if (err) throw err;
      report("Created",doc);
      callback(null,doc._id);
    });
  },

  function(id,callback) {
    Mix.findById(id,function(err,doc) {
      if (err) throw err;
      report("Found",doc);
      callback(null);
    });
  },

  function(callback) {
    Mix.create({
      "maybe": "now", "we": "can", "have": "fun"
    },function(err,doc) {
      if (err) throw err;
      report("Created",doc);
      callback(null,doc._id);
    });

  },

  function(id,callback) {
    Mix.findById(id,function(err,doc) {
      if (err) throw err;
      report("Found",doc);
      console.log(
        "But does not have built in accessors when strict:false. So...\n"
      );

      console.log(
        "\"maybe\": \"%s\" \"we\": \"%s\" \"have\": \"%s\"\n",
        doc.get("maybe"), doc.get("we"), doc.get("have")
      );

      // Or get raw values
      console.log("In the raw!\n");
      var raw = doc.toObject();
      for ( var k in raw ) {
        console.log( "\"%s\": \"%s\"", k, raw[k] );
      }

      console.log("\nAnd again\n");
      console.log(
        "\"maybe\": \"%s\" \"we\": \"%s\" \"have\": \"%s\"\n",
        raw.maybe, raw.we, raw.have
      );

      callback();
    });
  },

],function(err) {
  console.log("done");
  process.exit();
});

如前所述,_id访问者仍然存在,默认情况下它存在,除非再次将其关闭。对于其他人,您使用.get()方法。如果您通常使用MongoDB update operators,通常更新通常不是问题。但是对于mongoose对象的任何JavaScript代码操作,您必须调用.set()

输出:

Created
{
    "__v": 0,
    "lets": "have",
    "some": "fun",
    "_id": "53bf6f09ac1add4b3b2386b9"
}

Found
{
    "_id": "53bf6f09ac1add4b3b2386b9",
    "lets": "have",
    "some": "fun",
    "__v": 0 
}

Created
{
    "__v": 0,
    "maybe": "now",
    "we": "can",
    "have": "fun",
    "_id": "53bf6f09ac1add4b3b2386ba"
}

Found
{
    "_id": "53bf6f09ac1add4b3b2386ba",
    "maybe": "now",
    "we": "can",
    "have": "fun",
    "__v": 0
}

But does not have built in accessors when strict:false. So...

"maybe": "now" "we": "can" "have": "fun"

In the raw!

"_id": "53bf6f09ac1add4b3b2386ba"
"maybe": "now"
"we": "can"
"have": "fun"
"__v": "0"

And again

"maybe": "now" "we": "can" "have": "fun"

done