Aggregate and lookup in subdocuments

Asked

Viewed 160 times

0

I’m having trouble returning a "Join" on mongodb using lookup on subdocuments. I may have modeled it wrong, if you could give me a few pointers I’d be grateful! :)

I have the following collections:

Students

{ 
"_id" : ObjectId("59b825c41e1f430cd8439361"), 
"atualizado_em" : ISODate("2017-09-20T01:21:51.900+0000"), 
"criado_em" : ISODate("2017-09-12T18:22:04.766+0000"), 
"nome" : "ADERLINDO SANTOS DA SILVA", 
"provas" : [
    {
        "simulado" : ObjectId("59b83cca794ab45fb304d25c"), 
        "_id" : ObjectId("59c1c35c500c97715b56095a"), 
        "questoes" : [                
            {
                "opcaoMarcada" : ObjectId("59b050e2794ab45fb304d110"), 
                "questao" : ObjectId("59b050e2794ab45fb304d10f"), 
                "_id" : ObjectId("59c1c35c500c97715b56095c"), 
                "flagcorreta" : false
            }, 
            {
                "opcaoMarcada" : ObjectId("59b0511d794ab45fb304d119"), 
                "questao" : ObjectId("59b0511d794ab45fb304d115"), 
                "_id" : ObjectId("59c1c35c500c97715b56095b"), 
                "flagcorreta" : null
            }
        ]
    }
]

}

Questaos

{ 
"_id" : ObjectId("59a835e748395a5cf2d2e817"), 
"enunciado" : "Enunciado da questão", 
"tags" : [ 'tag1', 'tag2', 'tag3' ], 
"opcoes" : [
    {
        "_id" : ObjectId("59a835e748395a5cf2d2e81c"), 
        "correta" : true, 
        "texto" : "Opção 1", 
        "marcacoes" : NumberInt(48)
    }, 
    {
        "_id" : ObjectId("59a835e748395a5cf2d2e81b"), 
        "texto" : "Opção 2", 
        "marcacoes" : NumberInt(6)
    }, 
    {
        "_id" : ObjectId("59a835e748395a5cf2d2e81a"), 
        "texto" : "Opção 3", 
        "marcacoes" : NumberInt(10)
    }
] 
"__v" : NumberInt(0), 
"atualizado_em" : ISODate("2017-09-21T00:44:27.223+0000"), 
"criado_em" : ISODate("2017-09-14T22:44:08.979+0000")

}

Result I need:

[
{ 
    "_id" : ObjectId("59b825c41e1f430cd8439361"), 
    "atualizado_em" : ISODate("2017-09-20T01:21:51.900+0000"), 
    "criado_em" : ISODate("2017-09-12T18:22:04.766+0000"), 
    "nome" : "Fulano de Tal", 
    "provas" : [
        {
            "_id" : ObjectId("59c1c35c500c97715b56095a"), 
            "questoes" : [                
                {
                    "questao" : "ENUNCIADO DA QUESTÃO", 
                    "opcaoMarcada" : "TEXTO COM A OPÇÃO MARCADA", 
                    "flagcorreta" : false
                }, 
                {
                    "questao" : "ENUNCIADO DA QUESTÃO", 
                    "opcaoMarcada" : "TEXTO COM A OPÇÃO MARCADA", 
                    "flagcorreta" : false
                }
            ]
        }
    ]
}

]

I started with something like this, but now I have no idea how to recover the option that the student marked in the test.

db.alunos.aggregate([
{ $match: { 'provas': { $size: 1 } } },    
{ $unwind:"$provas"},
{ $unwind:"$provas.questoes"},
{
  $lookup:
    {
      from: "questaos",
      localField: "provas.questoes.questao",
      foreignField: "_id",
      as: "questoesArray"
    }
},
{ $unwind: "$questoesArray" },
{ $group: {
    "_id": "$_id",        
    "nome": { "$first": "$nome" },
    "questoes": { "$push": "$questoesArray.enunciado" }
    } 
},
{ $sort: { nome: 1 } }

])

The result was as follows:

{ 
"_id" : ObjectId("59b825c51e1f430cd8439705"), 
"nome" : "ABIMAEL DE SOUSA ALVES",     
"questoes" : [
    "<p style=\"margin-left:0cm; margin-right:0cm\">Sabe-se que as novas tecnologias alteraram o quadro tradicional das principais m&iacute;dias que serviam para apresentar conte&uacute;dos educacionais. Hoje, n&atilde;o dispomos apenas de m&iacute;dias como o texto impresso, os sons das transmiss&otilde;es radiof&ocirc;nicas e as imagens do v&iacute;deo ou da televis&atilde;o, pois podemos contar com os novos dispositivos eletr&ocirc;nicos, ou seja, com as m&iacute;dias digitais. Por isso, as pr&aacute;ticas de leitura e de escrita ganham novas possibilidades educacionais, podendo ser vivenciadas e veiculadas n&atilde;o apenas no espa&ccedil;o da escola, j&aacute; que elas se virtualizam e s&atilde;o desterritorializadas, estendendo-se para ambientes virtuais e sendo exibidas em dispositivos como telefones celulares, <em>tablets</em> e <em>notebooks</em>, ao mesmo tempo em que convivem com os livros impressos e os cadernos.</p>\n\n<p style=\"margin-left:0cm; margin-right:0cm\">&nbsp;</p>\n\n<p style=\"margin-left:0cm; margin-right:0cm\">A partir do que &eacute; afirmado acima, &eacute; poss&iacute;vel concluir corretamente que:</p>", 
    "<p style=\"margin-left:36pt; margin-right:0cm\">As novas pr&aacute;ticas de leitura e de escrita no hipertexto eletr&ocirc;nico, as mudan&ccedil;as de comportamento nas redes sociais, as novas formas de se relacionar nos ambientes virtuais, as transa&ccedil;&otilde;es comerciais eletr&ocirc;nicas e a economia no mundo digital s&atilde;o algumas das manifesta&ccedil;&otilde;es que ocorrem no ciberespa&ccedil;o e podem ser associadas, corretamente, com:</p>", 
    "<p style=\"margin-left:0cm; margin-right:0cm\">&ldquo;A globaliza&ccedil;&atilde;o &eacute;, de certa forma, o &aacute;pice do processo de internacionaliza&ccedil;&atilde;o do mundo capitalista. [...] No fim do s&eacute;culo XX e gra&ccedil;as aos avan&ccedil;os da ci&ecirc;ncia, produziu-se um sistema de t&eacute;cnicas presidido pelas t&eacute;cnicas da informa&ccedil;&atilde;o, que passaram a exercer um papel de elo entre as demais, unindo-as e assegurando ao novo sistema t&eacute;cnico uma presen&ccedil;a planet&aacute;ria. S&oacute; que a globaliza&ccedil;&atilde;o n&atilde;o &eacute; apenas a exist&ecirc;ncia desse novo sistema de t&eacute;cnicas. Ela &eacute; tamb&eacute;m o resultado das a&ccedil;&otilde;es que asseguram a emerg&ecirc;ncia de um mercado dito global, respons&aacute;vel pelo essencial dos processos pol&iacute;ticos atualmente eficazes.&rdquo;&nbsp;</p>\n\n<p style=\"margin-left:0cm; margin-right:0cm; text-align:right\">SANTOS, Milton. Por uma outra globaliza&ccedil;&atilde;o: do pensamento &uacute;nico &agrave; consci&ecirc;ncia universal.&nbsp;</p>\n\n<p style=\"margin-left:0cm; margin-right:0cm; text-align:right\">Rio de Janeiro: Record, 2000, p. 23-24.&nbsp;</p>\n\n<p style=\"margin-left:0cm; margin-right:0cm; text-align:justify\">&nbsp;</p>\n\n<p style=\"margin-left:0cm; margin-right:0cm; text-align:justify\">Considerando o enunciado anterior, sobre o processo de globaliza&ccedil;&atilde;o na sociedade contempor&acirc;nea, assinale a alternativa correta.&nbsp;</p>", 
    "<p style=\"margin-left:0cm; margin-right:0cm\">Um dos componentes vitais em um sistema operacional &eacute; a estrutura que armazena dados sobre os processos em execu&ccedil;&atilde;o, muitas vezes chamada Bloco de Controle de Processos (BCP). Essa estrutura &eacute; manipulada por todos os mecanismos de gerenciamento do SO, o que evidentemente cria problemas de condi&ccedil;&atilde;o de corrida nesse acesso.</p>\n\n<p style=\"margin-left:0cm; margin-right:0cm\">Considerando essas informa&ccedil;&otilde;es, assinale a alternativa que apresenta, corretamente, o tratamento do acesso ao BCP em um SO.</p>", 
    "<p style=\"margin-left:0cm; margin-right:0cm\">Apesar de a aloca&ccedil;&atilde;o de mem&oacute;ria em blocos implicar em um mecanismo mais complexo para a convers&atilde;o entre endere&ccedil;os virtuais e endere&ccedil;os f&iacute;sicos, &eacute; a partir do seu conceito que o gerenciamento de mem&oacute;ria</p>\n\n<p style=\"margin-left:0cm; margin-right:0cm\">evoluiu para o que se tem hoje, com o uso de mem&oacute;ria cache e mem&oacute;ria virtual.</p>\n\n<p style=\"margin-left:0cm; margin-right:0cm\">Com base nessas informa&ccedil;&otilde;es, considere as afirmativas a seguir.</p>\n\n<p style=\"margin-left:0cm; margin-right:0cm\">I. O endere&ccedil;amento &eacute; facilitado por hardware especializado.</p>\n\n<p style=\"margin-left:0cm; margin-right:0cm\">II. O uso de p&aacute;ginas de tamanho igual a pot&ecirc;ncia de 2 permite um melhor gerenciamento.</p>\n\n<p style=\"margin-left:0cm; margin-right:0cm\">III. O uso de mem&oacute;ria cache elimina a necessidade de endere&ccedil;amento, pois trata as informa&ccedil;&otilde;es como linhas de cache.</p>\n\n<p style=\"margin-left:0cm; margin-right:0cm\">IV. Endere&ccedil;os virtuais n&atilde;o s&atilde;o necess&aacute;rios se n&atilde;o se usar mem&oacute;ria virtual.</p>\n\n<p style=\"margin-left:0cm; margin-right:0cm\">Assinale a alternativa correta.</p>", 
    "<p style=\"margin-left:0px; margin-right:0px\">O VFS (<em>Virtual File System</em>) &eacute; o mecanismo que permite que chamadas de sistemas gen&eacute;ricas possam ser executadas independentemente do sistema de arquivos usado ou do meio f&iacute;sico. Em rela&ccedil;&atilde;o aos objetos prim&aacute;rios do VFS, analise as afirma&ccedil;&otilde;es abaixo e assinale V, se verdadeiras, ou F, se falsas.</p>\n\n<p style=\"margin-left:0px; margin-right:0px\">( &nbsp;) Superbloco &eacute; utilizado para armazenar informa&ccedil;&otilde;es sobre um sistema de arquivos espec&iacute;fico.</p>\n\n<p style=\"margin-left:0px; margin-right:0px\">( &nbsp;) Inode representa um arquivo espec&iacute;fico. Cada arquivo &eacute; representado por um inode no Sistema de Arquivos.</p>\n\n<p style=\"margin-left:0px; margin-right:0px\">( &nbsp;) Dentry representa uma entrada de diret&oacute;rio. O objeto Dentry n&atilde;o corresponde a qualquer estrutura de dados armazenada em disco.</p>\n\n<p style=\"margin-left:0px; margin-right:0px\">&nbsp;</p>\n\n<p style=\"margin-left:0px; margin-right:0px\">A ordem correta de preenchimento dos par&ecirc;nteses, de cima para baixo, &eacute;:</p>", 
    "<p>Sobre o IPSec, assinale a alternativa correta.</p>", 
    "<p style=\"margin-left:0cm; margin-right:0cm\">Em um sistema distribu&iacute;do, a comunica&ccedil;&atilde;o __________ entre os processos origem e destino ocorre quando um envio (<em>send</em>) &eacute; realizado. Neste caso, o processo origem &eacute; __________ at&eacute; que a recep&ccedil;&atilde;o (<em>receive</em>) correspondente seja realizada. A comunica&ccedil;&atilde;o __________ ocorre quando a opera&ccedil;&atilde;o envio (<em>send</em>) &eacute; __________ e a transmiss&atilde;o da mensagem ocorre __________ com o processo origem.</p>\n\n<p style=\"margin-left:0cm; margin-right:0cm\">Assinale a alternativa que preenche, correta e respectivamente, as lacunas do trecho acima.</p>", 
    "<p>Em uma rede de computadores, cujos roteadores est&atilde;o configurados para atualizar suas tabelas de roteamento por meio do emprego de protocolos de roteamento, &eacute; correto afirmar:</p>", 
    "<p style=\"margin-left:0cm; margin-right:0cm\">O mecanismo de RPC &eacute; bastante utilizado para a programa&ccedil;&atilde;o em sistemas distribu&iacute;dos.</p>\n\n<p style=\"margin-left:0cm; margin-right:0cm\">Implementa&ccedil;&otilde;es mais eficientes desse mecanismo permitem a realiza&ccedil;&atilde;o de RPC ass&iacute;ncrono, em que</p>"
]

}

1 answer

0

I hope it helps. see that you expect to have a reference to the Collections objectId

db.alunos.aggregate([
   { $unwind: "$provas" },
   { $unwind: "$provas.questoes" },
   {
        $lookup: {
            from: "questaos",
            localField: "provas.questoes.questao",
            foreignField: "opcoes._id",
            as: "questoesArray"
        }
    },
    { $unwind: { path: "$questoesArray", preserveNullAndEmptyArrays: true } },
    {
        $project: {
            'nome': '$nome',
            'atualizado_em': '$atualizado_em',
            'criado_em': '$criado_em',
            'provasId': '$provas._id',
            'provas': {
                $map: {
                    input: '$questoesArray.opcoes',
                    as: 'opcoes',
                    in: {
                        'questoes': {
                            $cond: [
                                { $eq: ['$provas.questoes.questao', '$$opcoes._id'] },
                                '$$opcoes', null
                            ]
                        }
                    }
                }
            }
        }
    },
      { $unwind: { path: "$provas", preserveNullAndEmptyArrays: false } },
      {
        "$match": {
            "provas.questoes": { "$exists": true, "$ne": null }
        }
    },
    {
                $group: {
                    _id: {
                          '_id': '$_id',
                          'nome': '$nome',
                          'atualizado_em': '$atualizado_em', 
                          'criado_em': '$criado_em',
                          'provasId': '$provasId',
                    },
                    'questoes': {
                        $addToSet: {
                            name: "$provas.questoes"
                          
                        }
                    }
                }
            },
               {
                $project: {

                        '_id': '$_id._id',
                        'nome': '$_id.nome',
                        'atualizado_em': '$_id.atualizado_em',
                        'criado_em': '$_id.criado_em',
                        'provas': {
                          '_id': '$_id.provasId',
                          'questoes': '$questoes'
                        }
                                              
                }
            }
])

{ 
"_id" : ObjectId("59c3e1e49d8a432da7b78867"), 
"nome" : "Jaffar cardoso", 
"atualizado_em" : ISODate("2017-09-20T01:21:51.900+0000"), 
"criado_em" : ISODate("2017-09-12T18:22:04.766+0000"), 
"provas" : {
    "_id" : ObjectId("59c3e1e49d8a432da7b78868"), 
    "questoes" : [
        {
            "name" : {
                "_id" : ObjectId("59a835e748395a5cf2d2e81b"), 
                "texto" : "Opção 2", 
                "marcacoes" : NumberInt(6)
            }
        }, 
        {
            "name" : {
                "_id" : ObjectId("59a835e748395a5cf2d2e81c"), 
                "correta" : true, 
                "texto" : "Opção 1", 
                "marcacoes" : NumberInt(48)
            }
        }
    ]
}
}
{ 
"_id" : ObjectId("59b825c41e1f430cd8439361"), 
"nome" : "ADERLINDO SANTOS DA SILVA", 
"atualizado_em" : ISODate("2017-09-20T01:21:51.900+0000"), 
"criado_em" : ISODate("2017-09-12T18:22:04.766+0000"), 
"provas" : {
    "_id" : ObjectId("59c1c35c500c97715b56095a"), 
    "questoes" : [
        {
            "name" : {
                "_id" : ObjectId("59b0511d794ab45fb304d115"), 
                "texto" : "Opção 3", 
                "marcacoes" : NumberInt(10)
            }
        }, 
        {
            "name" : {
                "_id" : ObjectId("59a835e748395a5cf2d2e81c"), 
                "correta" : true, 
                "texto" : "Opção 1", 
                "marcacoes" : NumberInt(48)
            }
        }
    ]
}
}
  • Hello friend, thanks for the return! I have not tested yet because I am without access to the base due to the earthquake in Mexico :/ foreignField: "options. _id", and then made a map. I’m dying to understand, could you help me understand this part? I’m still getting the hang of mongodb’s pipeline, it’s still confusing for me. I appreciate the attention and the response! As soon as I can test I’ll come back here and validate as a response.

  • I don’t know what language you are using, but it could make the result in the programming.. I just made a projectile so I could get the final result.

  • @Rafaeljourdan managed to test .. the script

Browser other questions tagged

You are not signed in. Login or sign up in order to post.