麻烦与Mongoose和Schema.Types.Mixed

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

版本:

 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 

你使用“瀑布”实际上是不正确的。 如果你期望这些variables在你的最终操作中是可见的,那么你需要通过所有的variables。 所以每个连续的callback都需要“传递”你收到的variables。 这些不只是自动“下降”最低水平。

在这里虽然真正的问题。

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

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

这并不限制领域,基本上一切正常。 “混合”实际上只适用于字段和types可能不同的字段定义。

在这种情况下保留了默认的_id作为ObjectId,但是你似乎并没有重写。


再看一遍这个问题, 从文档中错过了"strict": false这一点"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访问器仍然存在,它是默认的,除非你再次closures。 对于其他人,虽然你使用.get()方法。 如果您通常使用MongoDB 更新操作符,更新通常不是那么多问题。 但是对于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