Per qualsiasi documento di persona in particolare, puoi utilizzare il populate()
funzione come
var query = mongoose.model("person").find({ "name": "foo" }).populate("projects.tags");
E se vuoi cercare persone che hanno tag con 'MongoDB' o 'Node JS', ad esempio, puoi includere l'opzione di query in populate()
sovraccarico della funzione come:
var query = mongoose.model("person").find({ "name": "foo" }).populate({
"path": "projects.tags",
"match": { "en": { "$in": ["MongoDB", "Node JS"] } }
});
Se vuoi che tutti i tag siano presenti in "project.tags"
per tutte le persone, allora il quadro di aggregazione è la strada da percorrere. Prendi in considerazione l'esecuzione di questa pipeline sulla raccolta di persone e utilizza il $lookup
operatore per eseguire un join sinistro sulla raccolta di tag:
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);
})
Per ogni persona in particolare applica un $match
pipeline come primo passaggio per filtrare i documenti:
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);
})
Un'altra soluzione alternativa se stai utilizzando le versioni di MongoDB>=2.6 o <=3.0 che non supportano il $lookup
l'operatore deve popolare i risultati dell'aggregazione come:
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 ));
});
});