Mongodb,使用$ lookup进行聚合查询 [英] Mongodb, aggregate query with $lookup
问题描述
有两个大学,标签和人员.
Got two collecetions, tags and persons.
标签模型:
{
en: String,
sv: String
}
人物模型:
{
name: String,
projects: [
title: String,
tags: [
{
type: Schema.ObjectId,
ref: 'tag'
}
]
]
}
我想要查询返回个人模型中正在使用的所有标签的查询.所有文件.
I want query that returns all tags that is in use in the person model. All documents.
像这样
var query = mongoose.model('tag').find({...});
还是我应该以某种方式使用聚合方法?
Or should I somehow use the aggregate approach to this?
推荐答案
For any particular person document, you can use the populate()
function like
var query = mongoose.model("person").find({ "name": "foo" }).populate("projects.tags");
例如,如果要搜索带有"MongoDB"或"Node JS"标签的任何人,则可以在populate()
函数重载中包括以下查询选项:
And if you want to search for any persons that have any tag with 'MongoDB' or 'Node JS' for example, you can include the query option in the populate()
function overload as:
var query = mongoose.model("person").find({ "name": "foo" }).populate({
"path": "projects.tags",
"match": { "en": { "$in": ["MongoDB", "Node JS"] } }
});
如果希望所有人在"project.tags"
中都存在所有标签,则可以使用聚合框架.考虑在人员集合上运行此管道,并使用 $lookup
运算符对标签集合进行左连接:
If you want all tags existing in "project.tags"
for all persons, then aggregation framework is the way to go. Consider running this pipeline on the person collection and uses the $lookup
operator to do a left join on the tags collection:
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);
})
对于任何特定的人,然后应用 $match
管道作为过滤文档的第一步:
For any particular person then apply a $match
pipeline as the first step to filter the documents:
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);
})
如果使用的MongoDB版本> = 2.6或< = 3.0,则不支持
Another workaround if you are using MongoDB versions >= 2.6 or <= 3.0 which do not have support for the $lookup
operator is to populate the results from the aggregation as:
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 ));
});
});
这篇关于Mongodb,使用$ lookup进行聚合查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!