Đối với bất kỳ tài liệu cá nhân cụ thể nào, bạn có thể sử dụng populate()
chức năng như
var query = mongoose.model("person").find({ "name": "foo" }).populate("projects.tags");
Và nếu bạn muốn tìm kiếm bất kỳ người nào có bất kỳ thẻ nào với 'MongoDB' hoặc 'Node JS', ví dụ:bạn có thể bao gồm tùy chọn truy vấn trong populate()
quá tải hàm như:
var query = mongoose.model("person").find({ "name": "foo" }).populate({
"path": "projects.tags",
"match": { "en": { "$in": ["MongoDB", "Node JS"] } }
});
Nếu bạn muốn tất cả các thẻ hiện có trong "project.tags"
đối với tất cả mọi người, thì khung tổng hợp là con đường để đi. Cân nhắc chạy đường dẫn này trên tập hợp người và sử dụng $lookup
toán tử để thực hiện phép nối trái trên bộ sưu tập thẻ:
mongoose.model('person').aggregate([
{ "$unwind": "$projects" },
{ "$unwind": "$projects.tags" },
{
"$lookup": {
"from": "tags",
"localField": "projects.tags",
"foreignField": "_id",
"as": "resultingTagsArray"
}
},
{ "$unwind": "$resultingTagsArray" },
{
"$group": {
"_id": null,
"allTags": { "$addToSet": "$resultingTagsArray" },
"count": { "$sum": 1 }
}
}
]).exec(function(err, results){
console.log(results);
})
Đối với bất kỳ người cụ thể nào, hãy áp dụng $match
là bước đầu tiên để lọc tài liệu:
mongoose.model('person').aggregate([
{ "$match": { "name": "foo" } },
{ "$unwind": "$projects" },
{ "$unwind": "$projects.tags" },
{
"$lookup": {
"from": "tags",
"localField": "projects.tags",
"foreignField": "_id",
"as": "resultingTagsArray"
}
},
{ "$unwind": "$resultingTagsArray" },
{
"$group": {
"_id": null,
"allTags": { "$addToSet": "$resultingTagsArray" },
"count": { "$sum": 1 }
}
}
]).exec(function(err, results){
console.log(results);
})
Một giải pháp khác nếu bạn đang sử dụng các phiên bản MongoDB> =2.6 hoặc <=3.0 không hỗ trợ $lookup
toán tử là điền các kết quả từ tổng hợp dưới dạng:
mongoose.model('person').aggregate([
{ "$unwind": "$projects" },
{ "$unwind": "$projects.tags" },
{
"$group": {
"_id": null,
"allTags": { "$addToSet": "$projects.tags" }
}
}
], function(err, result) {
mongoose.model('person')
.populate(result, { "path": "allTags" }, function(err, results) {
if (err) throw err;
console.log(JSON.stringify(results, undefined, 4 ));
});
});