View a markdown version of this page

$graphLookup - Amazon DocumentDB

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

$graphLookup

Novo na versão 8.0.2.

O estágio $graphLookup de agregação no Amazon DocumentDB realiza uma pesquisa recursiva em uma coleção. Para cada documento de entrada, $graphLookup começa com um ou mais valores e combina repetidamente um campo de conexão com um campo de destino, seguindo a cadeia de documentos correspondentes até que não haja mais correspondências ou uma profundidade de recursão opcional seja alcançada. Isso é útil para percorrer dados hierárquicos ou semelhantes a gráficos, como estruturas de relatórios organizacionais, árvores de categorias ou relacionamentos de rede.

Parâmetros

  • from: A coleção de destino a ser pesquisada recursivamente. A from coleção deve estar no mesmo banco de dados.

  • startWith: a expressão que especifica o valor ou valores com os quais iniciar a pesquisa recursiva. Esse valor é comparado com o connectToField dos documentos na from coleção. Se for startWith avaliada como uma matriz, a pesquisa será executada em todos os elementos da matriz ao mesmo tempo.

  • connectFromField: o nome do campo cujo valor é usado para se conectar ao próximo documento na pesquisa recursiva. Se o valor for uma matriz, cada elemento será seguido individualmente pela travessia.

  • connectToField: o nome do campo na from coleção que é comparado com o valor doconnectFromField.

  • as: o nome do campo de matriz adicionado a cada documento de saída. Esse campo contém os documentos encontrados durante a pesquisa recursiva. Para obter informações sobre a ordem desses documentos, consulte o item Ordenação de resultados na seção Comportamento a seguir.

  • maxDepth: um número inteiro não negativo que especifica o número máximo de iterações recursivas a serem executadas após a pesquisa inicial. Esse parâmetro é opcional. Um valor de 0 executa somente a correspondência inicial e nenhuma recursão. Se você omitirmaxDepth, a pesquisa continuará recursivamente até que não haja mais documentos correspondentes.

  • depthField: o nome do campo a ser adicionado a cada documento na as matriz que contém a profundidade de recursão na qual o documento foi encontrado. Esse parâmetro é opcional. A profundidade é representada como a NumberLong e começa em zero, então a pesquisa inicial corresponde a uma profundidade de0.

  • restrictSearchWithMatch: um documento que especifica uma condição de correspondência adicional aplicada aos documentos da pesquisa. Esse parâmetro é opcional. A condição usa a mesma sintaxe de consulta como um $match estágio e não pode incluir expressões de agregação.

nota

O $graphLookup palco está sujeito a um limite de memória de 100 MB e não suportaallowDiskUse:true. Uma operação que excede esse limite retorna um erro. Se a agregação incluir outros estágios, a allowDiskUse:true opção permanecerá em vigor para esses estágios.

Comportamento

  • Cross-collection traversal: from defina a coleção que você deseja pesquisar. Essa pode ser a mesma coleção em que o pipeline é executado ou uma coleção diferente no mesmo banco de dados.

  • Ordenação dos resultados: os documentos na as matriz não são retornados em nenhuma ordem garantida.

Exemplo (MongoDB Shell)

O exemplo a seguir é usado $graphLookup para percorrer uma hierarquia de relatórios de funcionários e, para cada funcionário, colocar toda a cadeia de gerentes acima deles.

Os comandos a seguir, executados no shell mongosh, inserem exemplos de documentos de funcionários que estabelecem uma hierarquia de relatórios:

db.employees.insertMany([ { _id: 1, name: "Dev", reportsTo: "Eliot" }, { _id: 2, name: "Eliot", reportsTo: "Ron" }, { _id: 3, name: "Ron", reportsTo: "Andrew" }, { _id: 4, name: "Andrew", reportsTo: "Asya" }, { _id: 5, name: "Asya" } ]);

A agregação a seguir retorna a cadeia de gerenciamento completa de cada funcionário em uma nova reportingHierarchy matriz:

db.employees.aggregate([ { $graphLookup: { from: "employees", startWith: "$reportsTo", connectFromField: "reportsTo", connectToField: "name", as: "reportingHierarchy", depthField: "level" } } ]);

Essa operação retorna a seguinte saída:

[ { _id: 1, name: 'Dev', reportsTo: 'Eliot', reportingHierarchy: [ { _id: 2, name: 'Eliot', reportsTo: 'Ron', level: 0 }, { _id: 3, name: 'Ron', reportsTo: 'Andrew', level: 1 }, { _id: 4, name: 'Andrew', reportsTo: 'Asya', level: 2 }, { _id: 5, name: 'Asya', level: 3 } ] }, { _id: 2, name: 'Eliot', reportsTo: 'Ron', reportingHierarchy: [ { _id: 3, name: 'Ron', reportsTo: 'Andrew', level: 0 }, { _id: 4, name: 'Andrew', reportsTo: 'Asya', level: 1 }, { _id: 5, name: 'Asya', level: 2 } ] }, { _id: 3, name: 'Ron', reportsTo: 'Andrew', reportingHierarchy: [ { _id: 4, name: 'Andrew', reportsTo: 'Asya', level: 0 }, { _id: 5, name: 'Asya', level: 1 } ] }, { _id: 4, name: 'Andrew', reportsTo: 'Asya', reportingHierarchy: [ { _id: 5, name: 'Asya', level: 0 } ] }, { _id: 5, name: 'Asya', reportingHierarchy: [] } ]

Cada documento do funcionário ganha uma reportingHierarchy matriz que contém os documentos do gerente correspondentes recursivamente. O level campo registra a profundidade da recursão na qual cada gerente foi encontrado. Asya não tem reportsTo valor, então sua reportingHierarchy matriz está vazia.

Exemplo com maxDepth e restrict SearchWithMatch (MongoDB Shell)

O exemplo a seguir percorre uma rede de conexões entre pessoas e usuários maxDepth para limitar a recursão e incluir somente documentos que correspondam restrictSearchWithMatch a uma condição adicional. A pesquisa encontra as conexões de uma pessoa inicial, com até dois níveis de profundidade, mantendo apenas as pessoas cuja hobbies matriz contémgolf.

Os comandos a seguir, executados no shell mongosh, inserem exemplos de documentos nos quais cada pessoa friends aponta para frente por meio de uma cadeia unidirecional de conexões:

db.people.insertMany([ { _id: 1, name: "Tanya", friends: [ "Carole", "Shirley" ], hobbies: [ "tennis", "golf" ] }, { _id: 2, name: "Carole", friends: [ "Joseph" ], hobbies: [ "archery", "golf" ] }, { _id: 3, name: "Joseph", friends: [ "Angelo" ], hobbies: [ "tennis", "golf" ] }, { _id: 4, name: "Angelo", friends: [ "Miguel" ], hobbies: [ "travel", "golf" ] }, { _id: 5, name: "Miguel", friends: [], hobbies: [ "golf" ] }, { _id: 6, name: "Shirley", friends: [], hobbies: [ "frisbee" ] } ]);

A agregação a seguir começa com Tanya, percorre sua rede de conexões com até dois níveis de profundidade e mantém apenas as pessoas que golf listam como hobby:

db.people.aggregate([ { $match: { name: "Tanya" } }, { $graphLookup: { from: "people", startWith: "$friends", connectFromField: "friends", connectToField: "name", as: "golfConnections", maxDepth: 2, restrictSearchWithMatch: { hobbies: "golf" } } }, { $project: { name: 1, "golfConnections.name": 1 } } ]);

Essa operação retorna a seguinte saída:

[ { _id: 1, name: 'Tanya', golfConnections: [ { name: 'Carole' }, { name: 'Joseph' }, { name: 'Angelo' } ] } ]

Somente as conexões cuja hobbies matriz contém golf são incluídas e a travessia é interrompida após dois níveis de recursão. Shirley é excluída porque ela não listagolf, e Miguel é excluído porque está a três níveis de distância de Tanya, além do de. maxDepth 2 Como as conexões formam uma cadeia unidirecional que nunca aponta para Tanya, o documento inicial não é correspondido durante a pesquisa recursiva.

Exemplos de código

Para ver um exemplo de código que cria a hierarquia de relatórios de funcionários a partir do primeiro exemplo usando um driver MongoDB, escolha a guia do idioma que você deseja usar:

Node.js
const { MongoClient } = require('mongodb'); async function example() { const client = new MongoClient('mongodb://<username>:<password>@<cluster-endpoint>:27017/?tls=true&tlsCAFile=global-bundle.pem&replicaSet=rs0&readPreference=secondaryPreferred&retryWrites=false'); try { await client.connect(); const db = client.db('test'); const employees = db.collection('employees'); const result = await employees.aggregate([ { $graphLookup: { from: 'employees', startWith: '$reportsTo', connectFromField: 'reportsTo', connectToField: 'name', as: 'reportingHierarchy', depthField: 'level' } } ]).toArray(); console.log(JSON.stringify(result, null, 2)); } catch (err) { console.error('Failed to run $graphLookup aggregation:', err.message); } finally { await client.close(); } } example();
Python
from pymongo import MongoClient from pymongo.errors import PyMongoError def example(): client = MongoClient('mongodb://<username>:<password>@<cluster-endpoint>:27017/?tls=true&tlsCAFile=global-bundle.pem&replicaSet=rs0&readPreference=secondaryPreferred&retryWrites=false') try: db = client['test'] employees = db['employees'] pipeline = [ { "$graphLookup": { "from": "employees", "startWith": "$reportsTo", "connectFromField": "reportsTo", "connectToField": "name", "as": "reportingHierarchy", "depthField": "level" } } ] result = list(employees.aggregate(pipeline)) for doc in result: print(doc) except PyMongoError as error: print(f"Failed to run $graphLookup aggregation: {error}") finally: client.close() example()