一、模型关联
1、一对多/多对多
在一中关联多中的字段,type为mongoose.Schema.Types.ObjectId
,并关联关联模型的名称。
const categorySchema = new mongoose.Schema({
name: {type: String}
})
const tagSchema = new mongoose.Schema({
name: {type: String}
})
const articleSchema = new mongoose.Schema({
title: {type: String},
content: {type: String},
/* 一对多字段为一个对象 */
category: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Category' // 关联的模型
},
/* 多对多字段为一个数组 */
tags: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'Tag'
}]
})
2、关联模型的查询
(1)一对多查询
从关联对象中查询
const category = await Article.find().populate('category')
console.log(category)
结果为一个数组,数组中的对象含有category对象
[ { tags: [ 5ced005cf0b6b50fe429ffdb, 5ced005df0b6b50fe429ffdc ],
_id: 5cecff6c9d129a1520c4fa9c,
title: 'article1',
content: 'article1',
__v: 1,
category: { _id: 5ced0007037e041ec0560c1a, name: 'node', __v: 0 } },
{ tags: [ 5ced005df0b6b50fe429ffdc ],
_id: 5cecff6d9d129a1520c4fa9d,
title: 'article2',
content: 'article2',
__v: 1,
category: { _id: 5ced0008037e041ec0560c1b, name: 'vue', __v: 0 } } ]
(2)多对多查询
const tag = await Article.find().populate('tags')
console.log(tag)
结果为数组,被关联对象字段也是一个数组,包含多个对象
[ { tags: [ [Object], [Object] ],
_id: 5cecff6c9d129a1520c4fa9c,
title: 'article1',
content: 'article1',
__v: 1,
category: 5ced0007037e041ec0560c1a },
{ tags: [ [Object] ],
_id: 5cecff6d9d129a1520c4fa9d,
title: 'article2',
content: 'article2',
__v: 1,
category: 5ced0008037e041ec0560c1b } ]
3、从被关联模型中查询关联模型
(1)设置虚拟字段
在被关联模型中设置虚拟字段
categorySchema.virtual('articles', { // 定义虚拟字段
ref: 'Article', // 关联的模型
localField: '_id', // 内键,Category模型的id字段
foreignField: 'category', // 外键,关联模型的category字段
justOne: false // 只查询一条数据
})
const tagSchema = new mongoose.Schema({
name: {type: String}
})
tagSchema.virtual('articles', {
ref: 'Article',
localField: '_id',
foreignField: 'tags',
justOne: false
})
(2)查询
const article = await Tag.find().populate('articles')
console.log(article)
结果表面上看起来没有其他字段的信息,但虚拟字段的内容已经包括在内了;
[ { _id: 5ced005cf0b6b50fe429ffdb, name: 'tag1', __v: 0 },
{ _id: 5ced005df0b6b50fe429ffdc, name: 'tag2', __v: 0 } ]
继续在结果的数组中选择一个对象,并查询articles字段;
const article = await Tag.find().populate('articles')
console.log(article[0].articles)
结果就会为tag为tag1的所有文章。
[ { tags: [ 5ced005cf0b6b50fe429ffdb, 5ced005df0b6b50fe429ffdc ],
_id: 5cecff6c9d129a1520c4fa9c,
title: 'article1',
content: 'article1',
__v: 1,
category: 5ced0007037e041ec0560c1a } ]