sql >> Database >  >> NoSQL >> MongoDB

Mongodb, geaggregeerde zoekopdracht met $lookup

Voor elk specifiek persoonsdocument kunt u de populate() . gebruiken functioneren als

var query = mongoose.model("person").find({ "name": "foo" }).populate("projects.tags");

En als u wilt zoeken naar personen die een tag hebben met bijvoorbeeld 'MongoDB' of 'Node JS', kunt u de zoekoptie opnemen in de populate() functie overbelasting als:

var query = mongoose.model("person").find({ "name": "foo" }).populate({
    "path": "projects.tags",
    "match": { "en": { "$in": ["MongoDB", "Node JS"] } }
});

Als u wilt dat alle tags aanwezig zijn in "project.tags" voor alle personen, dan is een aggregatiekader de juiste keuze. Overweeg deze pijplijn uit te voeren op de persoonsverzameling en gebruik de $lookup operator om een ​​left join uit te voeren op de tagsverzameling:

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);
 })

Pas voor een bepaalde persoon een $match toe pijplijn als de eerste stap om de documenten te filteren:

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);
 })

Een andere oplossing als u MongoDB-versies>=2.6 of <=3.0 gebruikt die geen ondersteuning bieden voor de $lookup operator is om de resultaten van de aggregatie in te vullen als:

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 ));
    });
});


  1. Hoe kan ik MongoDB-logberichten in de console uitschakelen?

  2. MongoDB vergelijkt alleen datums zonder tijden

  3. Serialiseer een klas op twee verschillende manieren met Jackson

  4. Naadloze schaal voor uw MongoDB-servers