简体   繁体   中英

Expressjs Mongoose find nested embedded documents are undefined

I'm building a game with nodejs 0.6.18 expressjs 2.5.8 and mongoose 2.6.7.

I'm trying to store and retrieve embedded documents with mongoose. Consider this example :

User schema

var User = module.exports = new Schema({
      username: { type: String }
    , characters: [Character]
    , created: { type: Date, default: Date.now }
});

Character schema

var Character = module.exports = new Schema({
      name: { type: String }
    , spells: [Spell]
    , created: { type: Date, default: Date.now }
});

Spell schema

var Spell = module.exports = new Schema({
      name: { type: String }
    , created { type: Date, default: Date.now }
});

Mongoose

var db = mongoose.createConnection('mongodb://localhost/mygame');
mongoose.model('User', require('./models/user'));
mongoose.model('Character', require('./models/character'));
mongoose.model('Spell', require('./models/spell')

Route

app.get('/', function(req, res) {
  var User = db.model('User')
    , Character = db.model('Character')
    , Spell = db.model('Spell')
    , u = new User({username:'foo'})
    , c = new Character({name:'bar'});

  c.spells.push(new Spell({name:'fireball'}));
  c.spells.push(new Spell({name:'frozenball'}));
  u.characters.push(c);

  u.save(function(e, s) {
    User.find({username:'foo'}, function(err, success) {
      console.error(err);
      console.log(success);
    });
  });
});

Console output

null
[ { username: 'foo',
    _id: 4fda2c77faa9aa5c68000003,
    created: Thu, 14 Jun 2012 18:24:55 GMT,
    characters: [ undefined ] } ]

It looks like the User document is correctly saved and retrieved by mongoose. But, associated embedded documents are undefined .

I wanted to be sure that my document is saved, so I've directly asked to mongodb :

$ mongo mygame
> db.users.find({username:'foo'})
{
    "username" : "foo",
    "_id" : ObjectId("4fda2c77faa9aa5c68000003"),
    "created" : ISODate("2012-06-14T18:24:55.982Z"),
    "characters" : [
        {
            "name" : "bar",
            "_id" : ObjectId("4fda2c77faa9aa5c68000004"),
            "created" : ISODate("2012-06-14T18:24:55.986Z"),
            "spells" : [
                {
                    "name" : "fireball",
                    "_id" : ObjectId("4fda2c77faa9aa5c68000005"),
                    "created" : ISODate("2012-06-14T18:24:55.987Z")
                },
                {
                    "name" : "frozenball",
                    "_id" : ObjectId("4fda2c77faa9aa5c68000007"),
                    "created" : ISODate("2012-06-14T18:24:55.990Z")
                }
            ]
        }
    ]
}

As you can see, my documents seems to be correctly stored to mongodb, but I'm unable to retrieve whose who are embedded with mongoose.

I've also tried without the nested embedded Spell document, wich produce the exact same problem.

EDIT

@pat You are right. If I put all the Schemas directly in the same file (the main app.js for exemple) with the right order, it works.

The fact is, I would like to keep each models in separate files as much as possible (they are gonna grow a lot).

For exemple, my User model is contained in a file called models/user.js, and should be accessible using module.exports as above.

But, when I try to link my model to mongoose in an another file : mongoose.model('User', require('./models/user')); the mongoose find method returns undefined embedded documents.

Do you have any ideas on how to properly keep my mongoose models on separate files ?

The user schema file should first require the CharacterSchema at the top, then pass it in:

var CharacterSchema = require('./character');

var User = module.exports = new Schema({
      username: { type: String }
    , characters: [CharacterSchema]
    , created: { type: Date, default: Date.now }
});

Likewise, the CharacterSchema file should first require the SpellSchema at the top, then pass it:

var SpellSchema = require('./spell');
var CharacterSchema = module.exports = new Schema({ spells: [SpellSchema] })

This will retain their order.

Note: subdocs are not really needed to be models, since models are mapped to collections, but as long as you are not calling save directly on your subdocs they won't get saved to a separate collection in the db.

我认为,用户模式需要 Character and Spell 之后声明。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM