populate
Mongoose的populate()
函数是一个强大的工具,让你可以关联其他collections
的documents
。
关联的好处在于可以合并对数据库的request。
- 使用
populate()
之前
const recipeSchema = new mongoose.Schema(
{
title: {
type: String,
required: true,
minlength: 6,
maxlength: 255
},
materials: [
{
type: Schema.Types.ObjectId,
ref: 'Material',
required: false
}
]
});
const materialSchema = new mongoose.Schema(
{
name: {
type: String,
required: true
}
});
const Material = mongoose.model('material', materialSchema);
const Recipe = mongoose.model('recipe', recipeSchema);
const resolverMap = {
Query: {
recipes() {
console.log('Query.recipes info');
return Recipe.find();
},
recipe(_, { id }) {
return Recipe.findForOp(id);
}
}
};
在graphql的playgroud中获取recipes
query{
recipes{
id
title
image
materials{
name
}
}
}
得到命令行中console.log()
输出的信息
Query.recipes info
Query.materials info: 5bec111425c2be15fbcefec4
Query.materials info: 5becc04d25c2be15fbcefecb
Query.materials info: 5bf0b52e7dbe97559cfd0d52
可以看到总共进行了4次和数据库的交互
- 使用
populate()
之后
const recipeSchema = new mongoose.Schema(
{
title: {
type: String,
required: true,
minlength: 6,
maxlength: 255
},
materials: [
{
type: Schema.Types.ObjectId,
ref: 'Material',
required: false
}
]
});
const resolverMap = {
Recipe: {
},
Query: {
recipes() {
console.log('Query.recipes info');
return Recipe.find().populate({ path: 'materials', select: 'name' });
},
recipe(_, { id }) {
return Recipe.findForOp(id);
}
}
};
同样的graphql请求,命令行中的输出结果为
Query.recipes info
即只有一次数据请求