MongoDB 中文档引用关系的 Mongoose 实现
Mongoose implementation for Document Referenced Relationship in MongoDB
我需要使用文档引用关系(而不是嵌入文档)进行聚合查询。我能够使用 mongo shell 进行该查询,但在使用 mongoose.
的等效实现中苦苦挣扎
我试过虚拟填充方法,但它也返回空数组。这是一些定义上下文以及我的 mongo 查询的代码。我在父文档和子文档之间存在一对多关系。
//Parent Document
db.artists.insert(
{
_id : 4,
artistname : "Rush"
}
)
//Child Documents
db.musicians.insert(
{
_id : 9,
name : "Geddy Lee",
instrument : [ "Bass", "Vocals", "Keyboards" ],
artist_id : 4
}
)
db.musicians.insert(
{
_id : 10,
name : "Alex Lifeson",
instrument : [ "Guitar", "Backing Vocals" ],
artist_id : 4
}
)
db.musicians.insert(
{
_id : 11,
name : "Neil Peart",
instrument : "Drums",
artist_id : 4
}
)
//Query
db.artists.aggregate([
{
$lookup:
{
from: "musicians",
localField: "_id",
foreignField: "artist_id",
as: "band_members"
}
},
{ $match : { artistname : "Rush" } }
]).pretty()
//Result
{
"_id" : 4,
"artistname" : "Rush",
"band_members" : [
{
"_id" : 9,
"name" : "Geddy Lee",
"instrument" : [
"Bass",
"Vocals",
"Keyboards"
],
"artist_id" : 4
},
{
"_id" : 10,
"name" : "Alex Lifeson",
"instrument" : [
"Guitar",
"Backing Vocals"
],
"artist_id" : 4
},
{
"_id" : 11,
"name" : "Neil Peart",
"instrument" : "Drums",
"artist_id" : 4
}
]
}
//I've tried using populate, as well as aggregate. Here are both the implementations:
//Using populate
ArtistSchema.virtual('members', {
ref: 'MusicianCollection',
localField: '_id',
foreignField: 'artist_id',
justOne: false,
options: {limit: 5}
})
this.ArtistModel.findById(id).populate('members').exec((err, data) => {
if (err) console.log(err)
else artist = data
})
//in this i get a features array, but its empty
//Using aggregate
let artist = await this.ArtistModel.aggregate([
{ $match: { _id: id} },
{ $lookup: {
from: 'Musicians',
localField: '_id',
foreignField: 'artist_id',
as: 'members'
} }
]);
//in this the request times out
执行的很清楚。由于某些依赖项注入问题,我的无法正常工作。虽然这里的解决方案供参考:
为了避免在跨集合引用文档时使用引用 ID 数组,虚拟填充是可行的方法。
ArtistSchema.virtual('members', {
ref: 'MusicianCollection',
localField: '_id',
foreignField: 'artist_id',
justOne: false,
options: {limit: 5}
})
band = await this.ArtistModel.findById(id).populate('members').exec()
我需要使用文档引用关系(而不是嵌入文档)进行聚合查询。我能够使用 mongo shell 进行该查询,但在使用 mongoose.
的等效实现中苦苦挣扎我试过虚拟填充方法,但它也返回空数组。这是一些定义上下文以及我的 mongo 查询的代码。我在父文档和子文档之间存在一对多关系。
//Parent Document
db.artists.insert(
{
_id : 4,
artistname : "Rush"
}
)
//Child Documents
db.musicians.insert(
{
_id : 9,
name : "Geddy Lee",
instrument : [ "Bass", "Vocals", "Keyboards" ],
artist_id : 4
}
)
db.musicians.insert(
{
_id : 10,
name : "Alex Lifeson",
instrument : [ "Guitar", "Backing Vocals" ],
artist_id : 4
}
)
db.musicians.insert(
{
_id : 11,
name : "Neil Peart",
instrument : "Drums",
artist_id : 4
}
)
//Query
db.artists.aggregate([
{
$lookup:
{
from: "musicians",
localField: "_id",
foreignField: "artist_id",
as: "band_members"
}
},
{ $match : { artistname : "Rush" } }
]).pretty()
//Result
{
"_id" : 4,
"artistname" : "Rush",
"band_members" : [
{
"_id" : 9,
"name" : "Geddy Lee",
"instrument" : [
"Bass",
"Vocals",
"Keyboards"
],
"artist_id" : 4
},
{
"_id" : 10,
"name" : "Alex Lifeson",
"instrument" : [
"Guitar",
"Backing Vocals"
],
"artist_id" : 4
},
{
"_id" : 11,
"name" : "Neil Peart",
"instrument" : "Drums",
"artist_id" : 4
}
]
}
//I've tried using populate, as well as aggregate. Here are both the implementations:
//Using populate
ArtistSchema.virtual('members', {
ref: 'MusicianCollection',
localField: '_id',
foreignField: 'artist_id',
justOne: false,
options: {limit: 5}
})
this.ArtistModel.findById(id).populate('members').exec((err, data) => {
if (err) console.log(err)
else artist = data
})
//in this i get a features array, but its empty
//Using aggregate
let artist = await this.ArtistModel.aggregate([
{ $match: { _id: id} },
{ $lookup: {
from: 'Musicians',
localField: '_id',
foreignField: 'artist_id',
as: 'members'
} }
]);
//in this the request times out
执行的很清楚。由于某些依赖项注入问题,我的无法正常工作。虽然这里的解决方案供参考:
为了避免在跨集合引用文档时使用引用 ID 数组,虚拟填充是可行的方法。
ArtistSchema.virtual('members', {
ref: 'MusicianCollection',
localField: '_id',
foreignField: 'artist_id',
justOne: false,
options: {limit: 5}
})
band = await this.ArtistModel.findById(id).populate('members').exec()