Javascript 为什么';当我';我试图引用另一个模式的对象?

Javascript 为什么';当我';我试图引用另一个模式的对象?,javascript,node.js,mongodb,mongoose,Javascript,Node.js,Mongodb,Mongoose,我试图访问一个存储地址的属性,但我一直得到“未定义”。结果表明,地址只是一个id,即使我在地址的模式中声明了一个“ref”。我做错了什么 initStores的输出 { name: 'Wegmans', address: 53b998d9fcf740e07a4d03f7, _id: 53b998d9fcf740e07a4d03f8, items: [] } 53b998d9fcf740e07a4d03f7 undefined 路由器/index.js router.post('/i

我试图访问一个存储地址的属性,但我一直得到“未定义”。结果表明,地址只是一个id,即使我在地址的模式中声明了一个“ref”。我做错了什么

initStores的输出

{ name: 'Wegmans',
  address: 53b998d9fcf740e07a4d03f7,
  _id: 53b998d9fcf740e07a4d03f8,
  items: [] }
53b998d9fcf740e07a4d03f7
undefined
路由器/index.js

router.post('/initStores', function(req, res) {
    var address = new Address({
        street:     '650 Hylan Dr',
        city:       'Rochester',
        state:      'NY',
        zipcode:    '14623',
        telephone:  '123-456-7890'
    });
    // address.save();

    var store = new Store({
        name:   'Wegmans',
        address: address
    });

    console.log( store );
    console.log( store.address );
    console.log( store.address.street );
    // store.save();
}
models/address.js

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

var AddressSchema = new Schema({
    type:      { type: String, default: 'Store' }, // Store, apartment, house, headquarter
    street:    { type: String, require: true }, 
    city:      { type: String, require: true },
    state:     { type: String, require: true },
    zipcode:   { type: String, require: true },
    country:   { type: String, default: 'United States' },
    telephone: { type: String, default: '555-555-5555' }
});

mongoose.model('Address', AddressSchema);
models/store.js

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

var StoreSchema = new Schema({
    name:       { type: String, require: true },
    address:    { type: ObjectId, ref: 'Address' },
    items:      [ { type: ObjectId, ref: 'Item' } ]
});

mongoose.model( 'Store', StoreSchema );

对于引用的模式,此代码完全按照设计工作。“地址”模式中的字段根本不是“存储”模式的一部分。这里引用的设计只是存储相关文档的
\u id
值,文档的其余部分将驻留在它自己的集合中

因此,实际上,您实际上是在单独创建这些文档,并且只有在执行
.populate()
操作之后,不同的文档才会真正“显示”为“连接”,就像文档实际上“嵌入”时以本机方式显示一样

或者,由于您确实已经拥有“存储”对象,并且确保“保存”已完成:

async.series(
  [
    function(callback) {
      address.save(function(err,address) {
        callback();
      });
    },
    function(callback) {
      store.save(function(err,store) {
        Store.populate(store,{ path: "address"},function(err,store) {
          console.log(store);
          callback();
        });
      });
    }
  ]
);
在不需要保存数据的
.populate()
的情况下,这可以而且“应该”作为一个整体对象显示的唯一方法是嵌入地址,使其成为“存储”的一部分,而不是保存到不同的模型和集合:

var StoreSchema = new Schema({
    name:       { type: String, require: true },
    address:    { 
        "type":    { type: String, default: 'Store' }, // Store, apartment, house, headquarter
        street:    { type: String, require: true }, 
        city:      { type: String, require: true },
        state:     { type: String, require: true },
        zipcode:   { type: String, require: true },
        country:   { type: String, default: 'United States' },
        telephone: { type: String, default: '555-555-5555' }
    },
    items:      [ { type: ObjectId, ref: 'Item' } ]
});
或者,如果您的目的仅仅是登录创建,那么您可以使用
.toObject()
进行转换和操作:


但对于引用的模型,其目的是在调用
.populate()
之前,数据不是同一对象的一部分。

最初我想将地址存储在不同的集合中,但现在我看不到您指出的一点,即我可以将一个对象用作store的address属性,而且这个地址除了那个特定的商店之外不会被其他任何东西使用。谢谢你告诉我填充方法!我不知道你是如何访问其他属性的。
var StoreSchema = new Schema({
    name:       { type: String, require: true },
    address:    { 
        "type":    { type: String, default: 'Store' }, // Store, apartment, house, headquarter
        street:    { type: String, require: true }, 
        city:      { type: String, require: true },
        state:     { type: String, require: true },
        zipcode:   { type: String, require: true },
        country:   { type: String, default: 'United States' },
        telephone: { type: String, default: '555-555-5555' }
    },
    items:      [ { type: ObjectId, ref: 'Item' } ]
});
var raw = store.toObject();
raw.address = address.toObject();

console.log( raw );