View a markdown version of this page

$lookup - Amazon DocumentDB

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

$lookup

L'étape $lookup d'agrégation dans Amazon DocumentDB vous permet d'effectuer une jointure externe gauche entre deux collections. Cette opération vous permet de combiner des données provenant de plusieurs collections en fonction des valeurs de champs correspondantes. Il est particulièrement utile lorsque vous devez intégrer des données provenant de collections associées dans les résultats de votre requête.

Paramètres

  • from: nom de la collection avec laquelle effectuer la jointure.

  • localField: Le champ des documents d'entrée à comparer auforeignField.

  • foreignField: Le champ des documents de la from collection à comparer aulocalField.

  • as: nom du nouveau champ à ajouter aux documents de sortie contenant les documents correspondants de la from collection.

  • pipeline: Facultatif si localField et foreignField sont spécifiés. Un pipeline d'agrégation à exécuter sur la from collection. Le pipeline renvoie les documents de la from collection. Pour renvoyer tous les documents, indiquez un pipeline vide[]. Le pipeline ne peut pas inclure les $merge étapes $out ou. Consultez Conditions de jointure et sous-requêtes corrélées (MongoDB Shell).

  • let : facultatif. Un document qui définit les variables à utiliser dans les pipeline étapes. Utilisez les expressions variables pour accéder aux champs des documents d'entrée joints aupipeline. Pour référencer une variable dans les étapes du pipeline, utilisez la "$$<variable>" syntaxe. Consultez Conditions de jointure et sous-requêtes corrélées (MongoDB Shell).

Exemple (MongoDB Shell)

L'exemple suivant illustre une $lookup opération simple qui permet de joindre des données de la orders collection à la customers collection.

Créez des exemples de documents

db.customers.insertMany([ { _id: 1, name: "Alice" }, { _id: 2, name: "Bob" }, { _id: 3, name: "Charlie" } ]); db.orders.insertMany([ { _id: 1, customer_id: 1, total: 50 }, { _id: 2, customer_id: 1, total: 100 }, { _id: 3, customer_id: 2, total: 75 } ]);

Exemple de requête

db.customers.aggregate([ { $lookup: { from: "orders", localField: "_id", foreignField: "customer_id", as: "orders" } } ]);

Sortie

[ { _id: 1, name: 'Alice', orders: [ { _id: 2, customer_id: 1, total: 100 }, { _id: 1, customer_id: 1, total: 50 } ] }, { _id: 3, name: 'Charlie', orders: [] }, { _id: 2, name: 'Bob', orders: [ { _id: 3, customer_id: 2, total: 75 } ] } ]

Conditions de jointure et sous-requêtes corrélées (MongoDB Shell)

Nouveau depuis la version 8.0.2.

Outre une correspondance d'égalité unique, $lookup Amazon DocumentDB permet d'exécuter un pipeline d'agrégation sur la collection jointe. Cela prend en charge les sous-requêtes non corrélées, qui exécutent la même sous-requête pour chaque document d'entrée, et les sous-requêtes corrélées, qui utilisent des variables définies à partir des champs de chaque document d'entrée pour renvoyer des résultats corrélés à ce document.

Syntaxe

Pour exécuter une sous-requête corrélée, définissez des variables à partir des champs du document d'entrée avec et let référencez-les au cours des pipeline étapes suivantes :

{ $lookup: { from: <collection to join>, let: { <var_1>: <expression>, ..., <var_n>: <expression> }, pipeline: [ <pipeline to run on the joined collection> ], as: <output array field> } }

Paramètres

  • let: document qui définit des variables à partir des champs des documents d'entrée. Pour référencer une variable dans les étapes du pipeline, utilisez la "$$<variable>" syntaxe. Les variables sont accessibles par les étapes dupipeline, y compris les $lookup étapes supplémentaires imbriquées dans lepipeline. Une $match étape nécessite l'utilisation de l'$expropérateur pour accéder aux variables. Omettez let d'exécuter une sous-requête non corrélée.

  • pipeline: le pipeline d'agrégation à exécuter sur la from collection. Le pipeline ne peut pas accéder directement aux champs des documents d'entrée ; définissez les variables avec let et référencez les variables à la place. Pour renvoyer tous les documents, indiquez un pipeline vide[].

Les opérateurs $eq$gt,$gte,$lt, et de $lte comparaison placés dans un $expr opérateur au sein d'une $match étape peuvent utiliser un index sur la from collection lorsqu'ils comparent un champ de la collection jointe avec une let variable ou une constante.

Créez des exemples de documents

db.customers.insertMany([ { _id: 1, name: "Alice", min_total: 60 }, { _id: 2, name: "Bob", min_total: 50 }, { _id: 3, name: "Charlie", min_total: 20 } ]); db.orders.insertMany([ { _id: 1, customer_id: 1, total: 50 }, { _id: 2, customer_id: 1, total: 100 }, { _id: 3, customer_id: 2, total: 75 } ]);

Exemple de requête

L'exemple suivant associe chaque client à ses commandes et ne conserve que les commandes dont la valeur total est supérieure ou égale à la min_total valeur propre de ce client. La condition de jointure et le filtre par client font tous deux référence à let des variables dans $expr :

db.customers.aggregate([ { $lookup: { from: "orders", let: { customer_id: "$_id", min_total: "$min_total" }, pipeline: [ { $match: { $expr: { $and: [ { $eq: [ "$customer_id", "$$customer_id" ] }, { $gte: [ "$total", "$$min_total" ] } ] } } }, { $project: { _id: 0, total: 1 } } ], as: "qualifying_orders" } } ]);

Sortie

[ { _id: 1, name: 'Alice', min_total: 60, qualifying_orders: [ { total: 100 } ] }, { _id: 2, name: 'Bob', min_total: 50, qualifying_orders: [ { total: 75 } ] }, { _id: 3, name: 'Charlie', min_total: 20, qualifying_orders: [] } ]

Pour chaque client, la sous-requête est évaluée avec les min_total valeurs _id et de ce client, de sorte que chaque document reçoit son propre résultat corrélé.

Sous-requêtes corrélées utilisant une syntaxe concise (MongoDB Shell)

Nouveau depuis la version 8.0.2.

Amazon DocumentDB prend également en charge la syntaxe concise des sous-requêtes corrélées, qui combine la correspondance d'égalité sur localField et foreignField avec un. pipeline La syntaxe concise supprime l'obligation d'exprimer la correspondance d'égalité à l'intérieur d'un $expr opérateur d'une $match étape.

Syntaxe

{ $lookup: { from: <collection to join>, localField: <field from the input documents>, foreignField: <field from the documents of the "from" collection>, let: { <var_1>: <expression>, ..., <var_n>: <expression> }, pipeline: [ <pipeline to run> ], as: <output array field> } }

Exemple de requête

L'exemple suivant renvoie les mêmes résultats que l'exemple de sous-requête corrélée précédent. La correspondance d'égalité entre _id et customer_id est exprimée par localField et foreignField au lieu d'une $expr condition :

db.customers.aggregate([ { $lookup: { from: "orders", localField: "_id", foreignField: "customer_id", let: { min_total: "$min_total" }, pipeline: [ { $match: { $expr: { $gte: [ "$total", "$$min_total" ] } } }, { $project: { _id: 0, total: 1 } } ], as: "qualifying_orders" } } ]);

Sortie

[ { _id: 1, name: 'Alice', min_total: 60, qualifying_orders: [ { total: 100 } ] }, { _id: 2, name: 'Bob', min_total: 50, qualifying_orders: [ { total: 75 } ] }, { _id: 3, name: 'Charlie', min_total: 20, qualifying_orders: [] } ]

Étapes prises en charge dans les sous-requêtes corrélées

Lorsqu'un $lookup pipeline l'utiliselet, les étapes suivantes peuvent référencer les "$$<variable>" variables :

  • $match(à l'aide de l'$expropérateur)

  • $project

  • $addFields

  • $set

  • $group

  • $bucket

  • $bucketAuto

  • $sortByCount

  • $lookup(imbriqué)

  • $graphLookup

Les étapes qui n'évaluent pas les expressions variables$sort, telles que$skip,$limit,$count,$sample, et $unwind$unset, peuvent également être utilisées dans le pipeline mais ne peuvent pas référencer les variables.

Les étapes suivantes ne sont pas prises en charge dans un $lookup pipeline qui utilise let : $facet $redact $replaceRoot$replaceWith,$geoNear,$setWindowFields,$fill, et $match with$text.

Restrictions

  • Ils pipeline ne peuvent pas inclure les $merge étapes $out ou.

Exemples de code

Pour afficher un exemple de code d'utilisation de la $lookup commande, choisissez l'onglet correspondant à la langue que vous souhaitez utiliser :

Node.js
const { MongoClient } = require('mongodb'); async function example() { const client = await MongoClient.connect('mongodb://<username>:<password>@<cluster-endpoint>:27017/?tls=true&tlsCAFile=global-bundle.pem&replicaSet=rs0&readPreference=secondaryPreferred&retryWrites=false'); await client.connect(); const db = client.db('test'); const result = await db.collection('customers').aggregate([ { $lookup: { from: 'orders', localField: '_id', foreignField: 'customer_id', as: 'orders' } } ]).toArray(); console.log(JSON.stringify(result, null, 2)); await client.close(); } example();
Python
from pymongo import MongoClient def example(): client = MongoClient('mongodb://<username>:<password>@<cluster-endpoint>:27017/?tls=true&tlsCAFile=global-bundle.pem&replicaSet=rs0&readPreference=secondaryPreferred&retryWrites=false') db = client.test collection = db.customers pipeline = [ { "$lookup": { "from": "orders", "localField": "_id", "foreignField": "customer_id", "as": "orders" } } ] result = collection.aggregate(pipeline) for doc in result: print(doc) client.close() example()

Exemples de code de sous-requête corrélés

Pour afficher un exemple de code permettant d'utiliser la $lookup scène avec une sous-requête corrélée (utilisant let etpipeline), choisissez l'onglet correspondant à la langue que vous souhaitez utiliser :

Node.js
const { MongoClient } = require('mongodb'); async function example() { const client = await MongoClient.connect('mongodb://<username>:<password>@<cluster-endpoint>:27017/?tls=true&tlsCAFile=global-bundle.pem&replicaSet=rs0&readPreference=secondaryPreferred&retryWrites=false'); const db = client.db('test'); const customers = db.collection('customers'); await customers.insertMany([ { _id: 1, name: "Alice", min_total: 60 }, { _id: 2, name: "Bob", min_total: 50 }, { _id: 3, name: "Charlie", min_total: 20 } ]); const orders = db.collection('orders'); await orders.insertMany([ { _id: 1, customer_id: 1, total: 50 }, { _id: 2, customer_id: 1, total: 100 }, { _id: 3, customer_id: 2, total: 75 } ]); // Correlated subquery: filter each customer's orders with a per-customer threshold const result = await customers.aggregate([ { $lookup: { from: 'orders', localField: '_id', foreignField: 'customer_id', let: { min_total: '$min_total' }, pipeline: [ { $match: { $expr: { $gte: [ '$total', '$$min_total' ] } } }, { $project: { _id: 0, total: 1 } } ], as: 'qualifying_orders' } } ]).toArray(); console.log(JSON.stringify(result, null, 2)); await client.close(); } example();
Python
from pymongo import MongoClient def example(): client = MongoClient('mongodb://<username>:<password>@<cluster-endpoint>:27017/?tls=true&tlsCAFile=global-bundle.pem&replicaSet=rs0&readPreference=secondaryPreferred&retryWrites=false') db = client.test customers = db.customers customers.insert_many([ { "_id": 1, "name": "Alice", "min_total": 60 }, { "_id": 2, "name": "Bob", "min_total": 50 }, { "_id": 3, "name": "Charlie", "min_total": 20 } ]) orders = db.orders orders.insert_many([ { "_id": 1, "customer_id": 1, "total": 50 }, { "_id": 2, "customer_id": 1, "total": 100 }, { "_id": 3, "customer_id": 2, "total": 75 } ]) # Correlated subquery: filter each customer's orders with a per-customer threshold pipeline = [ { "$lookup": { "from": "orders", "localField": "_id", "foreignField": "customer_id", "let": { "min_total": "$min_total" }, "pipeline": [ { "$match": { "$expr": { "$gte": [ "$total", "$$min_total" ] } } }, { "$project": { "_id": 0, "total": 1 } } ], "as": "qualifying_orders" } } ] result = customers.aggregate(pipeline) for doc in result: print(doc) client.close() example()