繁体   English   中英

如何引用和填充嵌套模式?

[英]How to reference and populate nested schemas?

TL; DR如何引用(并填充)同一集合中的子文档?

我已经尝试了一段时间,以在Mongoose模式中填充对子文档的引用。 我有一个主架构(MainSchema),其中包含位置和联系人的数组。 这些位置参考了这些联系人。

在我的位置数组中,我通过联系人的_id引用了这些联系人。 见下文。

import mongoose from 'mongoose';

const LocationSchema = new mongoose.Schema({
  city: {type: String},
  contact: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'Contact' //alternative tried: refPath: 'contacts'
  } 
});
const Location = mongoose.model('Location', LocationSchema);

const ContactSchema = new mongoose.Schema({
  firstName: {type: String},
  lastName: {type: String}
});
const Contact = mongoose.model('Contact', ContactSchema );

const MainSchema = new mongoose.Schema({
  name: {type: String},
  locations: [LocationSchema],
  contacts: [ContactSchema]    
});

export.default mongoose.model('Main', 'MainSchema');

现在,当我想填充位置的联系人时,我会得到null或仅返回普通的_id字符串。 下面是我的填充代码。 我尝试了所有可能找到的组合,包括使嵌套文档成为自己的模型,并尝试使用不同的方式来引用它们。

MainSchema.statics = {
  get(slug) {
    return this.findOne({name})
      .populate('locations.contact')
      .exec()
      .then((company) => {
        if (company) {
          return company;
        }
        const err = 'generic error message';
        return Promise.reject(err);
      });
    }
  };

我也尝试了更新的方法,但无济于事:

populate({
  path: 'locations',
  populate: {
    path: 'contacts',
    model: 'Contact'
  }
});

我一定在这里想念什么。 但是呢

编辑了问题以显示要求的完整查询语句

因此,以您的架构示例为例,我将执行以下操作。 请注意,我并不是说我的方法是做到这一点的最佳方法,但我的情况与您完全相同。

猫鼬模型

import mongoose from 'mongoose';

const LocationSchema = new mongoose.Schema({
    city: {type: String},
    contact: { type: Schema.Types.ObjectId, ref: 'Contact'}
});

const ContactSchema = new mongoose.Schema({
    firstName: {type: String},
    lastName: {type: String}
});


const MainSchema = new mongoose.Schema({
    name: {type: String},
    locations: [{ type: Schema.Types.ObjectId, ref: 'Location' }],
});

const Main = mongoose.model('Main', MainSchema);
const Location = mongoose.model('Location', LocationSchema);
const Contact = mongoose.model('Contact', ContactSchema );

注意:在您的主模式中,由于我从您的示例中了解到每个位置都有自己的联系人,因此我已删除了联系人,因此实际上在MainSchema您不需要ContactSchema

您在其中插入数据的控制器

这里的想法是,您必须将每个文档的参考_id传递给另一个文档,下面的示例是模型,请对其进行调整以适合您的app 我使用了一个data对象,我假设它具有一个位置和一个人的联系方式

async function addData(data) {

    //First you create your Main document
    let main = await new Main({
        name: data.name
    }).save();

    //Create the contact document in order to have it's _id to pass into the location document
    let contact = await new Contact({
        firstName: data.fistName,
        lastName: data.lastName
    });

    //Create the location document with the reference _id from the contact document
    let location = await new Location({
        city: data.city,
        contact: contact._id
    }).save();

    //Push the location document in you Main document location array
    main.locations.push(location);
    main.save();

    //return what ever you need
    return main;
}

询问

let mainObj = await Main.findOne({name})
    .populate({path: 'locations', populate: {path: 'contact'}})
    .exec();

这种方法对我有用,希望对您也有帮助

经过更多搜索后,我发现在Mongoose github 问题跟踪器上发布了与问题完全相同的案例。

根据猫鼬的主要维护者,这种填充形式是不可能的:

如果要嵌入子文档,则将无法在数组上运行populate(),因为子文档存储在文档本身中,而不是存储在单独的集合中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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