猫鼬和schema的麻烦,类型,混合

Trouble with Mongoose and Schema.Types.Mixed

本文关键字:类型 混合 麻烦 schema      更新时间:2023-09-26

我试图有一个完全混合的模型,但不能真正让它工作,这是完整的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

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

主要问题是,即使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

你对"瀑布"的使用实际上是不正确的。如果你希望这些变量在你的最终操作中是可见的,那么你需要传递所有的变量。因此,每个连续的回调都需要"传递"接收到的变量。这些不会自动"瀑布式下降"到最底层。

说到真正的问题。

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

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

不限制字段,基本上一切都可以工作。"Mixed"实际上只适用于字段和类型可能不同的字段定义。

默认的_id作为ObjectId保留在这种情况下,但你似乎不重写,否则。


再看一下这个问题,文档中遗漏了"strict": false的要点。没有其他"定义"字段的访问器。您需要使用通用的.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更新操作符,则更新通常不是什么问题。但是对于任何对猫鼬对象的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