Recherche de site Web

Comment interroger des données dans MongoDB en utilisant Python : Un guide pour débutants


Introduction

MongoDB est une base de données NoSQL populaire et est largement utilisée pour gérer des données non structurées. Les développeurs Python peuvent interroger MongoDB efficacement en utilisant PyMongo, un pilote Python officiel pour MongoDB. Ce tutoriel couvrira diverses techniques de requête MongoDB en Python, y compris :

  • Récupération de documents à l'aide de filtres: Apprenez à utiliser PyMongo pour filtrer des documents en fonction de conditions spécifiques, telles que l'égalité, l'inégalité et les opérateurs logiques.
  • Interroger des champs imbriqués et des tableaux : Vous apprendrez comment accéder et manipuler des champs imbriqués et des tableaux dans les documents MongoDB en utilisant PyMongo.
  • Utilisation des pipelines d'agrégation: Utilisez le cadre d'agrégation de MongoDB pour traiter et transformer les données en plusieurs étapes, y compris le filtrage, le regroupement et le tri.
  • Meilleures pratiques pour optimiser les requêtes : Comprenez comment optimiser vos requêtes MongoDB pour de meilleures performances, y compris l'indexation, la limitation des résultats et la projection de champs spécifiques.

À la fin de ce tutoriel, vous serez en mesure de interroger des bases de données MongoDB de manière efficace en Python et de gérer l'optimisation des performances pour de grands ensembles de données. Nous discuterons également de la façon d'utiliser MongoDB Atlas, un service de base de données cloud entièrement géré, pour héberger vos bases de données MongoDB dans le cloud.

Conditions préalables

Avant de interroger MongoDB en Python, assurez-vous d'avoir ce qui suit :

  • Python 3 téléchargé et installé sur votre système.

  • MongoDB installé et en cours d'exécution. Vous pouvez vous référer à ce tutoriel pour savoir comment installer MongoDB.

  • Bibliothèque Pymongo installée.

  • Un cluster de base de données MongoDB Atlas gratuit déployé à des fins de démonstration et de test.

Étape 1 - Installer MongoDB sur Ubuntu

Pour installer MongoDB sur Ubuntu, suivez ces étapes :

Note: Les étapes ci-dessous sont exécutées sur un système Ubuntu version 24.10. Si vous utilisez une autre version d'Ubuntu, veuillez consulter cette documentation officielle sur la façon d'installer MongoDB sur Ubuntu.

  1. Importer la clé publique MongoDB:

    sudo apt-get install gnupg curl
    curl -fsSL https://www.mongodb.org/static/pgp/server-8.0.asc | sudo gpg -o /usr/share/keyrings/mongodb-server-8.0.gpg --dearmor
    
  2. Créer le fichier de liste :

    echo "deb [ arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb-server-8.0.gpg ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/8.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-8.0.list
    
  3. Rechargez la base de données des paquets:

    sudo apt-get update
    
  4. Installer MongoDB Community Edition:

    sudo apt-get install -y mongodb-org
    
  5. Démarrez le service MongoDB:

    sudo systemctl start mongod
    
  6. Vérifiez l'installation de MongoDB:

    sudo systemctl status mongod
    

Après avoir terminé ces étapes, MongoDB devrait être installé et en cours d'exécution sur votre système Ubuntu.

Étape 2 - Installer PyMongo

Créez un répertoire de projet

Dans votre terminal, exécutez la commande suivante pour créer un répertoire appelé pymongo-quickstart pour ce projet :

mkdir pymongo-quickstart

Exécutez les commandes suivantes pour créer un fichier d'application quickstart.py dans le répertoire pymongo-quickstart :

cd pymongo-quickstart
touch quickstart.py

Créons un environnement virtuel et activons-le :

python3 -m venv venv
source venv/bin/activate

Maintenant, installons PyMongo :

python3 -m pip install pymongo

Vous pouvez également suivre les étapes mentionnées dans cette documentation officielle de MongoDB sur la façon de télécharger et d'installer pymongo.

Étape 3 - Connexion à MongoDB Atlas en Python

Voici la structure des dossiers après l'installation de pymongo :

root/              
├── pymongo-quickstart/  
│   └──     quickstart.py  
    └──     venv

Dans cet exemple, nous allons utiliser MongoDB Atlas pour déployer un cluster MongoDB gratuit à des fins de démonstration. MongoDB Atlas est un service MongoDB basé sur le cloud qui permet aux utilisateurs de déployer, gérer et scaluer facilement des clusters MongoDB dans le cloud. Il offre une option gratuite, ce qui en fait un choix idéal pour les tests et les démonstrations.

Connectez-vous à MongoDB Cloud et créez un cluster gratuit MongoDB Atlas à partir de l'interface utilisateur Atlas.

Remarque : Une fois que votre cluster de base de données gratuit est créé, veuillez vous assurer d'ajouter l'adresse IP actuelle du système à partir duquel vous essayez de vous connecter à MongoDB.

Il suffit de visiter la section Accès au réseau de l'onglet Sécurité sur le tableau de bord du cluster MongoDB Atlas et d'ajouter l'adresse IP.

Si vous ne suivez pas cette étape, vous recevrez l'erreur Échec de la poignée de main SSL suivante lorsque vous mettrez en œuvre les étapes ci-dessous pour interroger les données.

pymongo.errors.ServerSelectionTimeoutError: SSL handshake failed: ac-r1katou-shard-00-01.1szm4t5.mongodb.net:27017: [SSL: TLSV1_ALERT_INTERNAL_ERROR] tlsv1 alert internal error (_ssl.c:1000) (configured timeouts: socketTimeoutMS: 20000.0ms, connectTimeoutMS: 20000.0ms),SSL handshake failed: ac-r1katou-shard-00-02.1szm4t5.mongodb.net:27017: [SSL: TLSV1_ALERT_INTERNAL_ERROR] tlsv1 alert internal error (_ssl.c:1000) (configured timeouts: socketTimeoutMS: 20000.0ms, connectTimeoutMS: 20000.0ms),SSL handshake failed: ac-r1katou-shard-00-00.1szm4t5.mongodb.net:27017: [SSL: TLSV1_ALERT_INTERNAL_ERROR] tlsv1 alert internal error (_ssl.c:1000) (configured timeouts: socketTimeoutMS: 20000.0ms, connectTimeoutMS: 20000.0ms), Timeout: 30s, Topology Description: <TopologyDescription id: 67e3a4be8b571dbdd9e11b91, topology_type: ReplicaSetNoPrimary, servers: [<ServerDescription ('ac-r1katou-shard-00-00.1szm4t5.mongodb.net', 27017) server_type: Unknown, rtt: None, error=AutoReconnect('SSL handshake failed: ac-r1katou-shard-00-00.1szm4t5.mongodb.net:27017: [SSL: TLSV1_ALERT_INTERNAL_ERROR] tlsv1 alert internal error (_ssl.c:1000) (configured timeouts: socketTimeoutMS: 20000.0ms, connectTimeoutMS: 20000.0ms)')>, <ServerDescription ('ac-r1katou-shard-00-01.1szm4t5.mongodb.net', 27017) server_type: Unknown, rtt: None, error=AutoReconnect('SSL handshake failed: ac-r1katou-shard-00-01.1szm4t5.mongodb.net:27017: [SSL: TLSV1_ALERT_INTERNAL_ERROR] tlsv1 alert internal error (_ssl.c:1000) (configured timeouts: socketTimeoutMS: 20000.0ms, connectTimeoutMS: 20000.0ms)')>, <ServerDescription ('ac-r1katou-shard-00-02.1szm4t5.mongodb.net', 27017) server_type: Unknown, rtt: None, error=AutoReconnect('SSL handshake failed: ac-r1katou-shard-00-02.1szm4t5.mongodb.net:27017: [SSL: TLSV1_ALERT_INTERNAL_ERROR] tlsv1 alert internal error (_ssl.c:1000) (configured timeouts: socketTimeoutMS: 20000.0ms, connectTimeoutMS: 20000.0ms)')>]

Pour interagir avec un cluster MongoDB Atlas, établissez une connexion en utilisant PyMongo. Nous utiliserons un ensemble de données d'exemple fourni par MongoDB Atlas.

Vous pouvez trouver la chaîne de connexion du cluster MongoDB Atlas dans l'onglet Aperçu -> Se connecter -> Instructions de connexion.

Ajoutez les lignes de code suivantes dans le fichier /root/pymongo-quickstart/quickstart.py :

import pymongo
from pymongo import MongoClient

Attempt to connect to the MongoDB cluster using the provided URI
try:
    uri = "mongodb+srv://<db_username>:<db_password>@cluster0.1szm4t5.mongodb.net/?retryWrites=true&w=majority&appName=Cluster0"
    client = MongoClient(uri)
    
    # Select the database and collection to work with
    database = client["sample_mflix"]
    collection = database["movies"]
    
    # This section is intentionally left blank for future code examples
    # Example code can be added here to interact with the MongoDB collection
    
    # Close the MongoDB client connection
    client.close()
except Exception as e:
    # If any error occurs during the connection or interaction, raise an exception with the error details
    raise Exception(
        "The following error occurred: ", e)

Récupérer un document d'échantillon en utilisant find_one()

La commande suivante récupère un seul document de film à partir du jeu de données.

Remarque : Vous devez ajouter les lignes de code pour interroger la base de données, discutées dans les sections suivantes de ce tutoriel, à l'intérieur du fichier /root/pymongo-quickstart/quickstart.py juste avant que la connexion à la base de données ne soit fermée en utilisant client.close().

print(collection.find_one())

Vous obtiendrez la sortie suivante après avoir exécuté le fichier Python :

python quickstart.py
{'_id': ObjectId('573a1390f29313caabcd42e8'), 'plot': 'A group of bandits stage a brazen train hold-up, only to find a determined posse hot on their heels.', 'genres': ['Short', 'Western'], 'runtime': 11, 'cast': ['A.C. Abadie', "Gilbert M. 'Broncho Billy' Anderson", 'George Barnes', 'Justus D. Barnes'], 'poster': 'https://m.media-amazon.com/images/M/MV5BMTU3NjE5NzYtYTYyNS00MDVmLWIwYjgtMmYwYWIxZDYyNzU2XkEyXkFqcGdeQXVyNzQzNzQxNzI@._V1_SY1000_SX677_AL_.jpg', 'title': 'The Great Train Robbery', 'fullplot': "Among the earliest existing films in American cinema - notable as the first film that presented a narrative story to tell - it depicts a group of cowboy outlaws who hold up a train and rob the passengers. They are then pursued by a Sheriff's posse. Several scenes have color included - all hand tinted.", 'languages': ['English'], 'released': datetime.datetime(1903, 12, 1, 0, 0), 'directors': ['Edwin S. Porter'], 'rated': 'TV-G', 'awards': {'wins': 1, 'nominations': 0, 'text': '1 win.'}, 'lastupdated': '2015-08-13 00:27:59.177000000', 'year': 1903, 'imdb': {'rating': 7.4, 'votes': 9847, 'id': 439}, 'countries': ['USA'], 'type': 'movie', 'tomatoes': {'viewer': {'rating': 3.7, 'numReviews': 2559, 'meter': 75}, 'fresh': 6, 'critic': {'rating': 7.6, 'numReviews': 6, 'meter': 100}, 'rotten': 0, 'lastUpdated': datetime.datetime(2015, 8, 8, 19, 16, 10)}, 'num_mflix_comments': 0}

Pour plus d'informations sur findOne(), consultez le tutoriel sur l'exemple de findOne() de MongoDB.

Récupération de documents en utilisant find()

La méthode find() récupère les documents qui correspondent à un filtre donné.

À l'intérieur du fichier quickstart.py, vous pouvez ajouter le code suivant pour interroger les données :

Get all movies
docs = collection.find().limit(5)
for movie in docs:
    print(movie)

Lorsque vous exécutez ce fichier Python, vous obtiendrez la sortie ci-dessous :

python quickstart.py
{'_id': ObjectId('573a1390f29313caabcd42e8'), 'plot': 'A group of bandits stage a brazen train hold-up, only to find a determined posse hot on their heels.', 'genres': ['Short', 'Western'], 'runtime': 11, 'cast': ['A.C. Abadie', "Gilbert M. 'Broncho Billy' Anderson", 'George Barnes', 'Justus D. Barnes'], 'poster': 'https://m.media-amazon.com/images/M/MV5BMTU3NjE5NzYtYTYyNS00MDVmLWIwYjgtMmYwYWIxZDYyNzU2XkEyXkFqcGdeQXVyNzQzNzQxNzI@._V1_SY1000_SX677_AL_.jpg', 'title': 'The Great Train Robbery', 'fullplot': "Among the earliest existing films in American cinema - notable as the first film that presented a narrative story to tell - it depicts a group of cowboy outlaws who hold up a train and rob the passengers. They are then pursued by a Sheriff's posse. Several scenes have color included - all hand tinted.", 'languages': ['English'], 'released': datetime.datetime(1903, 12, 1, 0, 0), 'directors': ['Edwin S. Porter'], 'rated': 'TV-G', 'awards': {'wins': 1, 'nominations': 0, 'text': '1 win.'}, 'lastupdated': '2015-08-13 00:27:59.177000000', 'year': 1903, 'imdb': {'rating': 7.4, 'votes': 9847, 'id': 439}, 'countries': ['USA'], 'type': 'movie', 'tomatoes': {'viewer': {'rating': 3.7, 'numReviews': 2559, 'meter': 75}, 'fresh': 6, 'critic': {'rating': 7.6, 'numReviews': 6, 'meter': 100}, 'rotten': 0, 'lastUpdated': datetime.datetime(2015, 8, 8, 19, 16, 10)}, 'num_mflix_comments': 0}
{'_id': ObjectId('573a1390f29313caabcd446f'), 'plot': "A greedy tycoon decides, on a whim, to corner the world market in wheat. This doubles the price of bread, forcing the grain's producers into charity lines and further into poverty. The film...", 'genres': ['Short', 'Drama'], 'runtime': 14, 'cast': ['Frank Powell', 'Grace Henderson', 'James Kirkwood', 'Linda Arvidson'], 'num_mflix_comments': 1, 'title': 'A Corner in Wheat', 'fullplot': "A greedy tycoon decides, on a whim, to corner the world market in wheat. This doubles the price of bread, forcing the grain's producers into charity lines and further into poverty. The film continues to contrast the ironic differences between the lives of those who work to grow the wheat and the life of the man who dabbles in its sale for profit.", 'languages': ['English'], 'released': datetime.datetime(1909, 12, 13, 0, 0), 'directors': ['D.W. Griffith'], 'rated': 'G', 'awards': {'wins': 1, 'nominations': 0, 'text': '1 win.'}, 'lastupdated': '2015-08-13 00:46:30.660000000', 'year': 1909, 'imdb': {'rating': 6.6, 'votes': 1375, 'id': 832}, 'countries': ['USA'], 'type': 'movie', 'tomatoes': {'viewer': {'rating': 3.6, 'numReviews': 109, 'meter': 73}, 'lastUpdated': datetime.datetime(2015, 5, 11, 18, 36, 53)}}
{'_id': ObjectId('573a1390f29313caabcd4803'), 'plot': 'Cartoon figures announce, via comic strip balloons, that they will move - and move they do, in a wildly exaggerated style.', 'genres': ['Animation', 'Short', 'Comedy'], 'runtime': 7, 'cast': ['Winsor McCay'], 'num_mflix_comments': 0, 'poster': 'https://m.media-amazon.com/images/M/MV5BYzg2NjNhNTctMjUxMi00ZWU4LWI3ZjYtNTI0NTQxNThjZTk2XkEyXkFqcGdeQXVyNzg5OTk2OA@@._V1_SY1000_SX677_AL_.jpg', 'title': 'Winsor McCay, the Famous Cartoonist of the N.Y. Herald and His Moving Comics', 'fullplot': 'Cartoonist Winsor McCay agrees to create a large set of drawings that will be photographed and made into a motion picture. The job requires plenty of drawing supplies, and the cartoonist must also overcome some mishaps caused by an assistant. Finally, the work is done, and everyone can see the resulting animated picture.', 'languages': ['English'], 'released': datetime.datetime(1911, 4, 8, 0, 0), 'directors': ['Winsor McCay', 'J. Stuart Blackton'], 'writers': ['Winsor McCay (comic strip "Little Nemo in Slumberland")', 'Winsor McCay (screenplay)'], 'awards': {'wins': 1, 'nominations': 0, 'text': '1 win.'}, 'lastupdated': '2015-08-29 01:09:03.030000000', 'year': 1911, 'imdb': {'rating': 7.3, 'votes': 1034, 'id': 1737}, 'countries': ['USA'], 'type': 'movie', 'tomatoes': {'viewer': {'rating': 3.4, 'numReviews': 89, 'meter': 47}, 'lastUpdated': datetime.datetime(2015, 8, 20, 18, 51, 24)}}
{'_id': ObjectId('573a1390f29313caabcd4eaf'), 'plot': 'A woman, with the aid of her police officer sweetheart, endeavors to uncover the prostitution ring that has kidnapped her sister, and the philanthropist who secretly runs it.', 'genres': ['Crime', 'Drama'], 'runtime': 88, 'cast': ['Jane Gail', 'Ethel Grandin', 'William H. Turner', 'Matt Moore'], 'num_mflix_comments': 1, 'poster': 'https://m.media-amazon.com/images/M/MV5BYzk0YWQzMGYtYTM5MC00NjM2LWE5YzYtMjgyNDVhZDg1N2YzXkEyXkFqcGdeQXVyMzE0MjY5ODA@._V1_SY1000_SX677_AL_.jpg', 'title': 'Traffic in Souls', 'lastupdated': '2015-09-15 02:07:14.247000000', 'languages': ['English'], 'released': datetime.datetime(1913, 11, 24, 0, 0), 'directors': ['George Loane Tucker'], 'rated': 'TV-PG', 'awards': {'wins': 1, 'nominations': 0, 'text': '1 win.'}, 'year': 1913, 'imdb': {'rating': 6.0, 'votes': 371, 'id': 3471}, 'countries': ['USA'], 'type': 'movie', 'tomatoes': {'viewer': {'rating': 3.0, 'numReviews': 85, 'meter': 57}, 'dvd': datetime.datetime(2008, 8, 26, 0, 0), 'lastUpdated': datetime.datetime(2015, 8, 10, 18, 33, 55)}}
{'_id': ObjectId('573a1390f29313caabcd50e5'), 'plot': 'The cartoonist, Winsor McCay, brings the Dinosaurus back to life in the figure of his latest creation, Gertie the Dinosaur.', 'genres': ['Animation', 'Short', 'Comedy'], 'runtime': 12, 'cast': ['Winsor McCay', 'George McManus', 'Roy L. McCardell'], 'num_mflix_comments': 0, 'poster': 'https://m.media-amazon.com/images/M/MV5BMTQxNzI4ODQ3NF5BMl5BanBnXkFtZTgwNzY5NzMwMjE@._V1_SY1000_SX677_AL_.jpg', 'title': 'Gertie the Dinosaur', 'fullplot': 'Winsor Z. McCay bets another cartoonist that he can animate a dinosaur. So he draws a big friendly herbivore called Gertie. Then he get into his own picture. Gertie walks through the picture, eats a tree, meets her creator, and takes him carefully on her back for a ride.', 'languages': ['English'], 'released': datetime.datetime(1914, 9, 15, 0, 0), 'directors': ['Winsor McCay'], 'writers': ['Winsor McCay'], 'awards': {'wins': 1, 'nominations': 0, 'text': '1 win.'}, 'lastupdated': '2015-08-18 01:03:15.313000000', 'year': 1914, 'imdb': {'rating': 7.3, 'votes': 1837, 'id': 4008}, 'countries': ['USA'], 'type': 'movie', 'tomatoes': {'viewer': {'rating': 3.7, 'numReviews': 29}, 'lastUpdated': datetime.datetime(2015, 8, 10, 19, 20, 3)}}

Filtrer les requêtes

Dans le fichier quickstart.py, nous pouvons ajouter le code suivant pour trouver des films sortis après l'année 2000.

Find movies released after 2000
query = {"year": {"$gt": 2000}}
for movie in collection.find(query).limit(2):
    print(movie)

Cela donnera la sortie ci-dessous :

{'_id': ObjectId('573a1393f29313caabcdcb42'), 'plot': 'Kate and her actor brother live in N.Y. in the 21st Century. Her ex-boyfriend, Stuart, lives above her apartment. Stuart finds a space near the Brooklyn Bridge where there is a gap in time....', 'genres': ['Comedy', 'Fantasy', 'Romance'], 'runtime': 118, 'metacritic': 44, 'rated': 'PG-13', 'cast': ['Meg Ryan', 'Hugh Jackman', 'Liev Schreiber', 'Breckin Meyer'], 'poster': 'https://m.media-amazon.com/images/M/MV5BNmNlN2VlOTctYTdhMS00NzUxLTg0ZGMtYWE2ZTJmMThlMTk2XkEyXkFqcGdeQXVyMzI0NDc4ODY@._V1_SY1000_SX677_AL_.jpg', 'title': 'Kate & Leopold', 'fullplot': "Kate and her actor brother live in N.Y. in the 21st Century. Her ex-boyfriend, Stuart, lives above her apartment. Stuart finds a space near the Brooklyn Bridge where there is a gap in time. He goes back to the 19th Century and takes pictures of the place. Leopold -- a man living in the 1870s -- is puzzled by Stuart's tiny camera, follows him back through the gap, and they both ended up in the present day. Leopold is clueless about his new surroundings. He gets help and insight from Charlie who thinks that Leopold is an actor who is always in character. Leopold is a highly intelligent man and tries his best to learn and even improve the modern conveniences that he encounters.", 'languages': ['English', 'French'], 'released': datetime.datetime(2001, 12, 25, 0, 0), 'directors': ['James Mangold'], 'writers': ['Steven Rogers (story)', 'James Mangold (screenplay)', 'Steven Rogers (screenplay)'], 'awards': {'wins': 2, 'nominations': 4, 'text': 'Nominated for 1 Oscar. Another 1 win & 4 nominations.'}, 'lastupdated': '2015-08-31 00:19:09.717000000', 'year': 2001, 'imdb': {'rating': 6.3, 'votes': 59951, 'id': 35423}, 'countries': ['USA'], 'type': 'movie', 'tomatoes': {'website': 'http://www.kateandleopold-themovie.com', 'viewer': {'rating': 3.0, 'numReviews': 189426, 'meter': 62}, 'dvd': datetime.datetime(2002, 6, 11, 0, 0), 'critic': {'rating': 5.3, 'numReviews': 126, 'meter': 50}, 'boxOffice': '$47.1M', 'consensus': 'Though Jackman charms, Kate and Leopold is bland and predictable, and the time travel scenario lacks inner logic.', 'rotten': 63, 'production': 'Miramax Films', 'lastUpdated': datetime.datetime(2015, 8, 22, 18, 53, 25), 'fresh': 63}, 'num_mflix_comments': 0}
{'_id': ObjectId('573a1398f29313caabceb1fe'), 'plot': "A modern day adaptation of Dostoyevsky's classic novel about a young student who is forever haunted by the murder he has committed.", 'genres': ['Drama'], 'runtime': 126, 'cast': ['Crispin Glover', 'Vanessa Redgrave', 'John Hurt', 'Margot Kidder'], 'poster': 'https://m.media-amazon.com/images/M/MV5BMTI3MDQ2MzEyOV5BMl5BanBnXkFtZTcwNzEwODUzMQ@@._V1_SY1000_SX677_AL_.jpg', 'title': 'Crime and Punishment', 'fullplot': "A modern day adaptation of Dostoyevsky's classic novel about a young student who is forever haunted by the murder he has committed.", 'languages': ['English', 'Polish'], 'released': datetime.datetime(2002, 6, 1, 0, 0), 'directors': ['Menahem Golan'], 'writers': ['Fyodor Dostoevsky (novel)', 'Menahem Golan (adaptation)', 'Menahem Golan (screenplay)'], 'awards': {'wins': 2, 'nominations': 0, 'text': '2 wins.'}, 'lastupdated': '2015-08-13 00:34:02.303000000', 'year': 2002, 'imdb': {'rating': 6.4, 'votes': 463, 'id': 96056}, 'countries': ['USA', 'Poland', 'Russia'], 'type': 'movie', 'tomatoes': {'viewer': {'rating': 0.0, 'numReviews': 0}, 'lastUpdated': datetime.datetime(2015, 7, 22, 18, 45, 10)}, 'num_mflix_comments': 0}

Filtrage de certaines colonnes

Dans le fichier quickstart.py, nous pouvons ajouter le code suivant pour trouver des films sortis après 2000 et n'afficher que le titre et la note IMDb.

Find movies released after 2000 and only display the title and IMDb rating
query = {"year": {"$gt": 2000}}  # This query filters movies released after the year 2000
projection = {"_id": 0, "title": 1, "imdb.rating": 1}  # This projection specifies which fields to include in the result
The "_id": 0 excludes the default "_id" field from the result, while "title": 1 and "imdb.rating": 1 include the title and IMDb rating respectively
for movie in collection.find(query, projection).limit(10):  # This loop iterates over the results of the query, limited to the first 10 matches
    print(movie)  # Each movie document is printed, showing only the title and IMDb rating as specified in the projection

Dans ce bloc de code, nous utilisons le paramètre projection dans la méthode find() pour spécifier quels champs inclure dans le résultat. Le champ _id est exclu du résultat avec "_id": 0, et les champs title et imdb.rating sont inclus avec 1. La méthode limit(10) est utilisée pour limiter le nombre de résultats à 10.

Vous pouvez en apprendre davantage sur les projections dans mongodb.

Voici la sortie :

{'title': 'Kate & Leopold', 'imdb': {'rating': 6.3}}
{'title': 'Crime and Punishment', 'imdb': {'rating': 6.4}}
{'imdb': {'rating': 2.1}, 'title': 'Glitter'}
{'imdb': {'rating': 5.5}, 'title': 'The Manson Family'}
{'title': 'The Dancer Upstairs', 'imdb': {'rating': 7.0}}
{'imdb': {'rating': 5.7}, 'title': 'Fantastic Four'}
{'imdb': {'rating': 7.4}, 'title': 'Frida'}
{'imdb': {'rating': 6.8}, 'title': 'From Hell'}
{'imdb': {'rating': 6.3}, 'title': 'Kate & Leopold'}
{'imdb': {'rating': 8.8}, 'title': 'The Lord of the Rings: The Fellowship of the Ring'}

Interroger des champs et tableaux imbriqués

Accéder à des champs imbriqués

Dans le code suivant, nous interrogeons la base de données pour trouver des films ayant une note IMDb supérieure ou égale à 8.

query = {"imdb.rating": {"$gte": 8}}
projection = {"_id": 0, "title": 1, "imdb.rating": 1}
for movie in collection.find(query, projection).limit(5):
    print(movie)

Ce bloc de code interroge la base de données pour trouver des films avec une note IMDb supérieure ou égale à 8. Il projette ensuite uniquement le titre et la note IMDb des films. La limite est fixée à 5, donc il ne renverra que les 5 premiers films qui correspondent à la requête.

Voici le résultat

{'title': 'One Week', 'imdb': {'rating': 8.3}}
{'title': "Tol'able David", 'imdb': {'rating': 8.1}}
{'title': 'Ella Cinders', 'imdb': {'rating': 8.1}}
{'title': 'City Lights', 'imdb': {'rating': 8.6}}
{'title': 'The Music Box', 'imdb': {'rating': 8.1}}

Filtrage des tableaux

Dans ce extrait de code, nous filtrons les films qui appartiennent au genre Action et projetons uniquement le titre et la note IMDb des films.

query = {"genres": "Action"}  # Finds movies that belong to the Action genre
projection = {"_id": 0, "title": 1, "imdb.rating": 1}
for movie in collection.find(query, projection).limit(10):
    print(movie)
{'title': 'The Perils of Pauline', 'imdb': {'rating': 7.6}}
{'title': 'From Hand to Mouth', 'imdb': {'rating': 7.0}}
{'title': 'Beau Geste', 'imdb': {'rating': 6.9}}
{'title': 'The Black Pirate', 'imdb': {'rating': 7.2}}
{'title': "For Heaven's Sake", 'imdb': {'rating': 7.6}}
{'title': 'Men Without Women', 'imdb': {'rating': 5.8}}
{'title': 'The Crowd Roars', 'imdb': {'rating': 6.4}}
{'title': 'Scarface', 'imdb': {'rating': 7.8}}
{'title': 'Tarzan the Ape Man', 'imdb': {'rating': 7.2}}
{'title': 'China Seas', 'imdb': {'rating': 7.0}}

Utiliser des pipelines d'agrégation pour des requêtes complexes

Les pipelines d'agrégation dans MongoDB sont un moyen de traiter les données en une série d'étapes. Chaque étape transforme les documents au fur et à mesure qu'ils passent à travers le pipeline. Cela permet des requêtes plus complexes et puissantes que les simples opérations de recherche.

This code block uses MongoDB's aggregation pipeline to process data in a series of stages.
The pipeline consists of two stages:
1. The "$match" stage filters the documents to only include those where the "year" field is greater than or equal to 2010.
2. The "$group" stage groups the filtered documents by their "genres" field and calculates the average "imdb.rating" for each group.
pipeline = [
    {"$match": {"year": {"$gte": 2010}}},
    {"$group": {"_id": "$genres", "averageIMDB": {"$avg": "$imdb.rating"}}}
]
The result of the aggregation pipeline is stored in the "result" variable.
result = collection.aggregate(pipeline)
Finally, the code iterates over the "result" and prints each document, which represents the average IMDb rating for each genre of movies released in or after 2010.
for doc in result:
    print(doc)

Ce bloc de code utilise le pipeline d'agrégation de MongoDB pour traiter des données en plusieurs étapes.

Le pipeline se compose de deux étapes :

  1. L'étape "match" filtre les documents pour n'inclure que ceux où le champ "année" est supérieur ou égal à 2010.
  2. L'étape « groupe » regroupe les documents filtrés par leur champ « genres » et calcule la note moyenne « imdb.rating » pour chaque groupe.

Le résultat du pipeline d'agrégation est stocké dans la variable "result".

Enfin, le code parcourt le "résultat" et imprime chaque document, qui représente la moyenne des notes IMDb pour chaque genre de films sortis en 2010 ou après.

Voici le résultat lorsque cette requête est exécutée :

{'_id': ['Comedy', 'Fantasy', 'Thriller'], 'averageIMDB': 6.4}
{'_id': ['Fantasy', 'Mystery', 'Thriller'], 'averageIMDB': 7.1}
{'_id': ['Comedy', 'Romance'], 'averageIMDB': 6.198165137614679}
{'_id': ['Animation', 'Short', 'Action'], 'averageIMDB': 7.1499999999999995}
{'_id': ['Action', 'Comedy', 'Fantasy'], 'averageIMDB': 6.2}
{'_id': ['Drama', 'War'], 'averageIMDB': 6.872413793103449}
{'_id': ['Horror', 'Sci-Fi', 'Thriller'], 'averageIMDB': 4.941666666666666}
{'_id': ['Documentary', 'Crime'], 'averageIMDB': 7.071428571428571}
{'_id': ['Animation', 'Short', 'Crime'], 'averageIMDB': 7.2}
{'_id': ['Documentary', 'History', 'News'], 'averageIMDB': 7.1000000000000005}
{'_id': ['Comedy', 'Crime', 'Thriller'], 'averageIMDB': 7.140000000000001}
{'_id': ['Comedy', 'Family', 'Romance'], 'averageIMDB': 6.24}
{'_id': ['Crime', 'Drama', 'Horror'], 'averageIMDB': 6.225}
{'_id': ['Comedy', 'Horror', 'Thriller'], 'averageIMDB': 5.642857142857143}
{'_id': ['Documentary', 'Animation', 'News'], 'averageIMDB': 7.2}
{'_id': ['Biography', 'Drama', 'War'], 'averageIMDB': 6.2}
{'_id': ['Fantasy', 'Thriller'], 'averageIMDB': 6.3}
{'_id': ['Drama', 'Horror', 'Mystery'], 'averageIMDB': 6.218181818181819}
{'_id': ['Adventure', 'Drama', 'Sci-Fi'], 'averageIMDB': 8.7}
{'_id': ['Comedy', 'Music'], 'averageIMDB': 6.359999999999999}
{'_id': ['Action', 'Comedy', 'Sport'], 'averageIMDB': 6.5}
{'_id': ['Drama', 'Family', 'Sci-Fi'], 'averageIMDB': 6.3}
{'_id': ['Action', 'Drama', 'Fantasy'], 'averageIMDB': 5.824999999999999}
{'_id': ['Drama', 'Music', 'Musical'], 'averageIMDB': 4.9}

Différences entre les méthodes find() et aggregate()

Caractéristiquetrouver()agréger()Exemple d'échantillon
SimplicitéSimpleComplexe
db.collection.find({}) vs db.collection.aggregate([{ $match: {} }])
PerformanceRapide pour des requêtes simplesOptimisé pour de grands ensembles de données
db.collection.find({ year: { $gte: 2010 } }) vs db.collection.aggregate([{ $match: { year: { $gte: 2010 } } }, { $group: { _id: "$genres", averageIMDB: { $avg: "$imdb.rating" } } }])
Cas d'utilisationFiltrage et récupération de donnéesTransformation et computation des données
db.collection.find({ genres: "Comedy" }) vs db.collection.aggregate([{ $match: { genres: "Comedy" } }, { $group: { _id: "$genres", count: { $sum: 1 } } }])

La méthode find() est un moyen simple de récupérer des données d'une collection MongoDB. Elle est idéale pour des requêtes simples nécessitant un filtrage et la récupération de données en fonction de conditions spécifiques. Cependant, elle présente des limites en ce qui concerne les transformations de données complexes et les calculs.

D'autre part, la méthode aggregate() est un outil puissant pour traiter des données en plusieurs étapes. Elle est conçue pour gérer des transformations de données complexes, des agrégations et des calculs. Bien qu'elle puisse être plus complexe à utiliser que find(), elle offre une large gamme d'opérateurs et d'étapes qui peuvent être combinés pour effectuer des tâches de traitement des données sophistiquées.

Lors de la décision entre find() et aggregate(), considérez la complexité de votre requête et le type de traitement des données requis. Si vous devez effectuer un filtrage et une récupération simples, find() pourrait être le meilleur choix. Cependant, si vous devez effectuer des transformations de données, des agrégations ou des calculs, aggregate() est probablement la meilleure option.

Optimisation des requêtes MongoDB pour la performance

Utiliser des index

Créer un index sur un champ peut considérablement améliorer les performances des requêtes, en particulier pour les champs utilisés dans les filtres ou les tris des requêtes. Dans cet exemple, nous créons un index sur le champ « année » pour optimiser les requêtes qui filtrent les films par année de sortie.

collection.create_index("year")

Limiter les résultats

Limiter le nombre de résultats retournés par une requête peut réduire la quantité de données transférées et traitées, ce qui améliore les performances. Cela est particulièrement utile lorsque vous n'avez besoin que d'un sous-ensemble des données ou que vous souhaitez implémenter la pagination. Ici, nous limitons les résultats aux 10 premiers films trouvés.

for movie in collection.find().limit(10):
    print(movie)

Champs spécifiques au projet

Projeter des champs spécifiques dans une requête vous permet de récupérer uniquement les données dont vous avez besoin, réduisant ainsi la quantité de données transférées et traitées. Cela peut améliorer les performances et réduire la surcharge réseau. Dans cet exemple, nous projetons uniquement le champ "titre" et excluons le champ "_id" pour afficher uniquement les titres des films.

for movie in collection.find({}, {"title": 1, "_id": 0}):
    print(movie)

FAQ

1. Comment puis-je interroger des données dans MongoDB en utilisant Python ?

Lors de la requête de données dans MongoDB en utilisant Python, vous avez deux méthodes principales : find() et aggregate(). Le choix entre ces méthodes dépend de la complexité de votre requête et du type de traitement des données requis.

Requêtes de base avec find()

La méthode find() est adaptée pour des requêtes simples qui nécessitent de filtrer et de récupérer des données en fonction de conditions spécifiques. Elle est idéale pour des tâches telles que :

  • Récupérer tous les documents d'une collection : db.collection.find()
  • Filtrer des documents en fonction d'une condition : db.collection.find({"year": 2010})
  • Récupérer des champs spécifiques : db.collection.find({}, {"title": 1, "_id": 0})

Voici un exemple d'utilisation de find() pour récupérer tous les films sortis en 2010 :

for movie in db.movies.find({"year": 2010}):
    print(movie)

Requêtes avancées avec aggregate()

La méthode aggregate() est conçue pour des transformations de données complexes, des agrégations et des calculs. Elle est idéale pour des tâches telles que :

  • Grouper des documents en fonction d'un champ et calculer une moyenne : db.collection.aggregate([{ $group: { _id: "$genres", averageIMDB: { $avg: "$imdb.rating" } } }])
  • Filtrer des documents en fonction d'une condition puis grouper : db.collection.aggregate([{ $match: { year: 2010 } }, { $group: { _id: "$genres", count: { $sum: 1 } } }])

Voici un exemple d'utilisation de aggregate() pour calculer la note moyenne IMDB des films dans chaque genre :

for result in db.movies.aggregate([{ $group: { _id: "$genres", averageIMDB: { $avg: "$imdb.rating" } } }]):
    print(result)

En résumé, utilisez find() pour des requêtes de base nécessitant un filtrage et une récupération simples, et utilisez aggregate() pour des requêtes avancées nécessitant des transformations de données complexes et des calculs.

2. Quelle est la différence entre find() et aggregate()?

La méthode find() est un moyen simple de récupérer des données d'une collection MongoDB. Elle est idéale pour des requêtes simples nécessitant un filtrage et une récupération de données basées sur des conditions spécifiques. Cependant, elle a des limites en ce qui concerne les transformations de données complexes et les calculs.

D'autre part, la méthode aggregate() est un outil puissant pour traiter des données en plusieurs étapes. Elle est conçue pour gérer des transformations de données complexes, des agrégations et des calculs. Bien qu'elle puisse être plus complexe à utiliser que find(), elle offre une large gamme d'opérateurs et d'étapes qui peuvent être combinés pour effectuer des tâches de traitement des données sophistiquées.

3. Comment filtrer des données dans MongoDB avec Python ?

Pour filtrer des données dans MongoDB en utilisant Python, vous pouvez utiliser la syntaxe { "field": { "$operator": value } }. Cette syntaxe vous permet de spécifier un champ, un opérateur et une valeur pour filtrer les données. Voici un exemple de code qui montre comment filtrer des documents où le champ “year” est égal à 2020 :

for movie in db.movies.find({"year": { "$eq": 2020 }}):
    print(movie)

4. Puis-je interroger des documents imbriqués dans MongoDB ?

Oui, vous pouvez interroger des documents imbriqués dans MongoDB en utilisant la notation par points. La notation par points vous permet d'accéder aux champs à l'intérieur des documents imbriqués. La syntaxe pour la notation par points est { "nested.field": value }.

Par exemple, si vous avez une structure de document comme celle-ci :

{
  "name": "John Doe",
  "address": {
    "street": "123 Main St",
    "city": "Anytown",
    "state": "CA",
    "zip": "12345"
  }
}

Vous pouvez interroger des documents où le champ « ville » dans le document imbriqué « adresse » est « Anytown » en utilisant le code suivant :

for document in db.collection.find({"address.city": "Anytown"}):
    print(document)

Cela renverra tous les documents où le champ “city ” dans le document imbriqué “address ” correspond à “Anytown ”.

5. Comment optimiser les requêtes MongoDB pour de grands ensembles de données ?

Vous pouvez utiliser des techniques telles que l'indexation, la projection et la limitation des résultats pour améliorer les performances, comme discuté dans les sections ci-dessus.

6. Quelles sont les meilleures bibliothèques pour interroger MongoDB en Python ?

  • pymongo (pilote officiel de MongoDB)

  • mongoengine (mappeur objet-document)

Pour plus de tutoriels sur la gestion de MongoDB, consultez notre série de tutoriels sur comment gérer des données avec MongoDB.

Conclusion

En conclusion, interroger MongoDB en Python est une compétence cruciale pour tout développeur travaillant avec de grands ensembles de données. Ce tutoriel a couvert diverses techniques de requête MongoDB en Python, y compris la récupération de documents en utilisant des filtres, l'interrogation de champs et de tableaux imbriqués, l'utilisation de pipelines d'agrégation et les meilleures pratiques pour optimiser les requêtes.

Dans ce tutoriel, vous avez appris :

  • Créer des requêtes de base en utilisant la méthode find() pour récupérer des documents spécifiques
  • Filtrer les champs et les tableaux imbriqués pour cibler des données spécifiques et réduire la quantité de données récupérées
  • Exploitation des pipelines d'agrégation en utilisant aggregate() pour un traitement de données complexe, tel que la transformation de données, le regroupement et le tri.
  • Optimiser les requêtes pour des performances sur de grands ensembles de données en utilisant des index, des projections et des limites pour réduire la charge sur la base de données et améliorer l'efficacité des requêtes.

En maîtrisant ces techniques, vous serez en mesure de récupérer et de manipuler efficacement des données dans vos collections MongoDB, ce qui vous rendra un développeur plus efficace dans la gestion de grands ensembles de données.

Pour en savoir plus, explorez :

  • Comment créer des requêtes dans la série de tutoriels MongoDB.

  • Comment créer des requêtes dans MongoDB.