<jupyter_start><jupyter_text>AggregatieMet aggragatie bedoelen we het *samenvatten* van de gegevens van een aantal documenten in een enkele waarde.Voorbeelden van aggregatie-operatoren zijn: `sum` (en daarmee ook `count`), `avg`, `min`, `max`.(Dit zijn ook typische aggregatie-functies in spreadsheets.)Dit samenvatten combineren we vaak met *groepering*: we willen de samenvattende waarde per groep weten.> In SQL heb je voor aggregatie dezelfde functies zoals hierboven genoemd;   deze gebruik je in het SELECT-deel van de query. Voor groepering gebruik je GROUP BY.Voor meer informatie over aggregatie in MongoDB, zie: https://docs.mongodb.com/manual/aggregationVoor de aggregatie-voorbeelden gebruiken we naast de contacten-collection, ook een collection met agenda-items. De onderstaande opdracht is nodig als initialisatie in sommige omgevingen.<jupyter_code>import os
os.environ["PATH"]=os.environ["PATH"] + ":/usr/local/bin"<jupyter_output><empty_output><jupyter_text>De gebruikelijke initialisatie:<jupyter_code>import os
import re
import pandas as pd
import numpy as np
from IPython.core.display import display, HTML
import pymongo

pd.set_option('max_colwidth',160)

userline = !echo $USER
username = userline[0]
dbname = username + "-demodb"
print("Database name: " + dbname)

print('Mongo version', pymongo.__version__)
client = pymongo.MongoClient('localhost', 27017)
db = client[dbname]

contacts = db.contacts
contacts.drop()
os.system('mongoimport -d ' + dbname + ' -c contacts adressen.json')
agenda = db.agenda
agenda.drop()
os.system('mongoimport -d ' + dbname + ' -c agenda agenda.json')
cursor = agenda.find()
list(cursor)<jupyter_output><empty_output><jupyter_text>Aggregatie in MongoDB: pijplijnDe `colelction.aggregate`-functie heeft een lijst van parameters (`[ {...stap...}, ...]`).Elk element is deze lijst is een stap in een *pijplijn*,waarbij elke stap het resultaat van de vorige stap verder bewerkt.De eerste stap werkt op alle documenten in de *collection*.Zie ook de figuur in: https://docs.mongodb.com/manual/aggregation/aggregationAls stap kun je onder andere de volgende functies gebruiken:* `$match`: selecteren (filteren) van documenten* `$group`: voor het groeperen en samenvatten van documenten* `$project`: selecteren van velden in de resultaat-documenten* `$lookup`: combineren van documenten uit verschillende collections ("join").Er zijn nog veel meer functies mogelijk in de aggregation-pijplijn,zie het MongoDB manual: https://docs.mongodb.com/manual/meta/aggregation-quick-reference/De `$lookup` en `$project` functies behandelen we in een volgend notebook.  Voorbeeld 1In het eerste voorbeeld tellen we het aantal contacten per plaats.We laten het `$match` query-document hier weg: we onderzoeken alle documenten in de collection.We groeperen per plaats (via de `_id`) en geven per plaats het aantal (`count`) dat we berekenen door 1 te sommeren voor alle documenten.Merk op dat je voor de veldnamen van het oorspronkelijke document **in het $group-deel een `$` schrijft.** Bijvoorbeeld: `$address.city`.<jupyter_code>cursor = contacts.aggregate([{"$group":{"_id": "$address.city", "count": {"$sum": 1} }}])
list(cursor)<jupyter_output><empty_output><jupyter_text>Voorbeeld 2Voor het tweede voorbeeld gebruiken we de agenda-items.Bekijk eerst het bestand [agenda.json](agenda.json) om een indruk te krijgen van de gegevens in deze items.We willen weten hoeveel tijd we voor de verschillende onderwerpen (`subject`) in de agenda hebben staan.Merk op dat voor de veldnamen in het $group-deel een `$` geschreven is: `$subject` en `$duration`.<jupyter_code>cursor = agenda.aggregate([{"$group":{"_id": "$subject", "count": {"$sum": "$duration"} }}])
list(cursor)<jupyter_output><empty_output><jupyter_text>OpdrachtMaak een query voor het bepalen van de totale tijd per vergaderlocatie (`location`).<jupyter_code>cursor = agenda.aggregate([{"$group":{"_id": "$location", "totaltime": {"$sum": "$duration"} }}])
list(cursor)<jupyter_output><empty_output><jupyter_text>Voorbeeld 3We gebruiken hier het `$match`-deel met een filter-document: we willen alleen de documenten waarvan de `participants` de persoon met email-adres: <EMAIL> bevat.Merk op dat dit een *normaal* filter-document is, als bij `collection.find`: de namen van de velden (properties) schrijf je hier zonder `$`.De totale vergadertijd per locatie met de persoon met email-adres: <EMAIL>:<jupyter_code>cursor = agenda.aggregate([{"$match": {"participants": { "email": "<EMAIL>"}}}, 
                           {"$group": {"_id": "$location", "count": {"$sum": "$duration"}}} ])
list(cursor)<jupyter_output><empty_output><jupyter_text>OpdrachtMaak een query voor het bepalen van de totale tijd *per vergaderlocatie*, voor het onderwerp (subject) "Beleidsplan".<jupyter_code>cursor = agenda.aggregate([
    {"$match": {"subject": "Beleidsplan"}},
    {"$group":{"_id": "$location", "totaltime": {"$sum": "$duration"} }}])
list(cursor)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.12271172802253068, 'fraction_numerical': 0.002816334741500704, 'mean_word_length': 6.123209169054442, 'pattern_counts': {'":': 26, '<': 32, '<?xml version=': 0, '>': 33, 'https://': 3, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '7', 'dir': 'jupyter-structured-clean-dedup', 'id': '257084', 'license': 'MIT', 'n_tokens_mistral': 1684, 'n_tokens_neox': 1665, 'n_words': 510, 'path': 'uitwerkingen/Aggregatie-uitwerkingen.ipynb', 'repo_name': 'eelcodijkstra/mongodb-binder', 'size': '4995'}