Ga naar hoofdinhoud

MongoDB-dotnotatie-tutorial: geneste velden opvragen

Leer enkele querytechnieken voor geneste documenten en arrays in MongoDB.
· 5 min lezen

Verken met AI

Als je net begint met MongoDB, ben je waarschijnlijk op een punt gekomen waarop je documenten wat complexer worden. Ze zijn misschien gegaan van platte, relationeel ogende data naar iets met geneste objecten, geneste arrays en misschien zelfs vier of vijf lagen dieper. Hoe voer je dan queries uit op data die een paar lagen diep zit?

In deze korte tutorial kijken we naar dotnotatie in MongoDB en zien we hoe je heel snel en eenvoudig documenten kunt filteren op basis van waarden in geneste velden.

Met dotnotatie bedoelen we het scheiden van geneste velden met een punt als scheidingsteken. Bijvoorbeeld:

root_field.nested_field_1.next_layer_nested_field_1

Voor elke laag van nesting voegen we bij het uitvoeren van een query gewoon een punt toe tussen die laag. We zullen uitgebreidere voorbeelden zien terwijl we doorgaan met de tutorial.

Als je net begint met MongoDB, bekijk dan zeker DataCamps Introduction to MongoDB in Python-cursus.

Vereisten

Om deze tutorial succesvol te volgen, heb je een MongoDB-instantie nodig die is uitgerold en geconfigureerd. Dat wil zeggen: je bent klaar om MongoDB te gaan gebruiken. Je moet ook op z'n minst basiskennis hebben van het uitvoeren van queries op collecties in MongoDB. De documentatie is een goed startpunt als je hulp nodig hebt.

Voor dit voorbeeld gebruiken we de volgende data in een "dbinc"-database en een "people"-collectie:

[
    {
        "name": "Nic Raboy",
        "websites": [
            {
                "type": "other",
                "name": "Portfolio",
                "url": "https://www.nraboy.com"
            },
            {
                "type": "social",
                "name": "LinkedIn",
                "url": "https://www.linkedin.com/in/nraboy"
            }
        ],
        "employment": {
            "employer": "MongoDB",
            "address": {
                "street": "1633 Broadway",
                "city": "New York",
                "state": "New York",
                "postal_code": 10019
            }
        }
    },
    {
        "name": "Tony Kim",
        "websites": [
            {
                "type": "social",
                "name": "LinkedIn",
                "url": "https://www.linkedin.com/in/hyung-kim/"
            },
            {
                "type": "coding",
                "name": "GitHub",
                "url": "https://github.com/hjkmines"
            }
        ],
        "employment": {
            "employer": "MongoDB",
            "address": {
                "street": "1633 Broadway",
                "city": "New York",
                "state": "New York",
                "postal_code": 10019
            }
        }
    }
]

De bovenstaande data vertegenwoordigt twee documenten met de nodige complexiteit, omdat ze geneste objecten en arrays bevatten. Leuk weetje: MongoDB ondersteunt meer dan 100 niveaus van nesting in BSON-documenten.

Als je wilt meedoen, zorg dan dat deze documenten in je MongoDB-instantie bestaan.

Data opvragen in MongoDB met verschillende aanpakken

We beginnen eenvoudig en gaan stap voor stap richting complexere gevallen. Het goede nieuws is dat complex hier niet per se moeilijk betekent.

Stel dat we alle mensen in onze collectie willen vinden die bij MongoDB werken. We kunnen dan een query uitvoeren zoals deze:

use dbinc;

db.people.find({
	"employment.employer": "MongoDB"
});

In dit voorbeeld is employer een genest veld binnen het employment-object. We kunnen op dat veld queryen met dotnotatie, wat simpelweg velden zijn die door punten gescheiden worden. Dit is niet anders dan wanneer we alle mensen zouden willen vinden die in New York werken. We zouden zoiets kunnen doen als het volgende:

use dbinc;

db.people.find({
	"employment.address.state": "New York"
});

In de bovenstaande query zochten we drie niveaus diep in het document, en dat werkte probleemloos.

Laten we nu kijken naar het werken met die geneste array van objecten. Er zijn een paar manieren om te queryen, afhankelijk van wat we willen doen.

Stel dat we alle mensen willen teruggeven die een "Portfolio"-website hebben vermeld. We kunnen dan een query uitvoeren zoals deze:

use dbinc;

db.people.find({
	"websites.name": "Portfolio"
});

De bovenstaande query levert één resultaat op, omdat slechts één van de documenten een "Portfolio" vermeldt. Merk op dat, ook al hebben we een array, dotnotatie hier nog steeds werkt. De kanttekening is dat "Portfolio" ergens in die array minimaal één keer moet voorkomen.

Hier wordt het interessant.

Stel dat we de resultaten verder willen beperken. Dat doen we door extra filtercriteria toe te voegen, maar bij geneste objecten binnen arrays werkt het net even anders. Neem bijvoorbeeld het volgende:

use dbinc;

db.people.find({
    "websites.name": "Portfolio",
    "websites.type": "social"
});

In het bovenstaande voorbeeld zeggen we dat we resultaten willen waar zowel "Portfolio" als "social" in de array voorkomen, maar niet per se in hetzelfde object. We krijgen slechts één resultaat terug, omdat het document van "Tony Kim" wel "social" heeft, maar geen "Portfolio". Als we resultaten nodig hebben waarbij beide velden in hetzelfde object moeten voorkomen, dan kunnen we daar geen dotnotatie voor gebruiken.

Hoewel het buiten de scope van deze tutorial valt, zou het gebruik van de operator $elemMatch zoals hier het gewenste resultaat opleveren:

use dbinc;

db.people.find(
    { 
        "websites": { 
            "$elemMatch": { 
                "name": "Portfolio",
                "type": "social" 
            }
        }
    }
);

In het bovenstaande scenario worden geen resultaten teruggegeven, omdat onze voorbeelddata geen overeenkomende name en type binnen hetzelfde object bevat.

Als je met arrays werkt en je kent de index in de array waarmee je wilt werken, dan kun je dotnotatie blijven gebruiken. Neem bijvoorbeeld het volgende:

use dbinc;

db.people.find({
    "websites.0.name": "Portfolio"
});

De bovenstaande query gebruikt de index van de array waarop je wilt matchen. In dit scenario willen we alle documenten teruggeven waarbij het eerste item in de array een name van "Portfolio" heeft.

Hoewel het buiten de scope van deze tutorial valt, is het goed om te noemen dat dotnotatie niet beperkt is tot alleen-lezen queries. Je kunt dotnotatie zoals hier gebruiken in update-operaties, projecties en aggregatiepipelines.

Conclusie

Je hebt zojuist een snelle introductie gekregen in het gebruik van dotnotatie in je MongoDB-queries. We leerden:

  • Dotnotatie werkt voor geneste objecten.
  • Je kunt dotnotatie gebruiken voor arrays, maar met beperkingen afhankelijk van je verwachtingen bij die arrays.
  • De operator $elemMatch is nodig als je meerdere velden binnen één enkel array-object wilt matchen.
  • Array-indexen binnen dotnotatie kunnen worden gebruikt als je op bepaalde elementen in een array wilt queryen.

De data in je MongoDB-collecties zal waarschijnlijk niet plat zijn; op een gegeven moment krijg je geneste objecten, geneste arrays, arrays in objecten en allerlei andere combinaties van complexiteit. Het goede nieuws is dat MongoDB het eenvoudig maakt om hiermee te werken via de rijke query-API.

Als je MongoDB nog niet gebruikt, bekijk dan MongoDB Atlas of mijn andere tutorial waarin aan de slag gaan met MongoDB en Docker wordt gedemonstreerd. Je kunt ook meer leren over MongoDB-certificering in onze aparte gids. 

FAQs

Wat is dotnotatie in MongoDB?

Dotnotatie is het benaderen van geneste velden in MongoDB-documenten met behulp van een punt als scheidingsteken.

Kan ik met meerdere geneste velden filteren in mijn queries?

Ja, je match-queries kunnen dotnotatie gebruiken op al je velden, op een deel ervan of op geen enkel veld. Het is hetzelfde filter—je benadert alleen geneste items.

Wat doe ik met mijn onvoorspelbare arrays?

Zorg ervoor dat je arrays niet onbegrensd groeien omwille van grootte en performance, maar ze met dotnotatie queryen werkt prima en blijft eenvoudig.

Wat als ik een document met geneste objecten en arrays moet updaten?

Bij een update-operatie werkt dotnotatie zowel in het filtergedeelte van de operatie als in het wijzigingsgedeelte.

Onderwerpen

Gerelateerd