Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

119
Visualizações
Agregado de MongoDB: reemplazo de una matriz de ID con los objetos correspondientes de una matriz en el mismo documento

Tengo los siguientes documentos en una colección:

 [{ id: 1, name: 'My document 1', allItems: [{ id: 'item1', name: 'My item 1' }, { id: 'item2', name: 'My item 2' }, { id: 'item3' name: 'My item 3' }], containers: [{ id: 'container1', selectedItems: [ 'item3', 'item1' ] }, { id: 'container2', selectedItems: [ 'item3' ] }] }, ...]

Ahora quiero escribir una consulta para encontrar el documento con un ID de contenedor específico (es decir container1 ) y devolverlo, mientras transformo su matriz de elementos selectedItems para contener los valores reales del objeto de la matriz allItems del mismo documento.

Quiero obtener este documento:

 { id: 1, name: 'My document 1', container: { id: 'container1', selectedItems: [{ id: 'item3' name: 'My item 3' }, { id: 'item1', name: 'My item 1' } } }

Actualmente tengo la siguiente agregación (Node.js):

 db.collection.aggregate([{ $match: {'containers.id': 'container1'}, $addFields: { container: { $filter: { input: '$containers', as: 'container', cond: { $eq: ['$$container.id', 'container1'] } } } }, $project: {containers: 0}, $unwind: {path: '$container'} // I now have a new property "container" with the correct subdocument from the array // and removed the original array with all containers. // I now need a stage here to populate the container subdocuments in the `selectedItems` array $project: {allItems: 0} // remove the list of all items when not needed anymore in a following stage }]);

Sé que hay $lookup , pero como quiero completar los elementos de matriz coincidentes del mismo documento (no una colección diferente), creo que no lo necesito. Incluso al especificar la misma colección en una $lookup , llenaría la matriz con el documento raíz de mi colección y se volvería muy complejo desenredar y hacer coincidir las propiedades necesarias del subdocumento.

Pensé en crear una colección de items propia, pero necesitaría búsquedas más lentas allí y mis datos no necesitan tener estas relaciones.

Espero que mi pregunta sea clara, ¡agradezco cualquier ayuda que pueda obtener!

Estoy haciendo algunas transformaciones adicionales en mis datos reales, como copiar algunas propiedades del documento raíz original y ocultar otras, pero eso no debería importar.

¡Gracias de nuevo!

about 4 years ago · Juan Pablo Isaza
2 Respostas
Responde à pergunta

0

  • $match tus condiciones
  • $filter para iterar el bucle de matriz de containers y filtrar por id
  • $arrayElemAt para seleccionar el primer elemento del resultado filtrado anterior
  • $let declarar una variable y almacenar hacer el proceso anterior y almacenar el resultado
  • $filter para iterar el bucle de la matriz allItems y filtrar los elementos por el resultado anterior
 db.collection.aggregate([ { $match: { "containers.id": "container1" } }, { $project: { name: 1, container: { $let: { vars: { container: { $arrayElemAt: [ { $filter: { input: "$containers", cond: { $eq: ["$$this.id", "container1"] } } }, 0 ] } }, in: { id: "$$container.id", selectedItems: { $filter: { input: "$allItems", cond: { $in: ["$$this.id", "$$container.selectedItems"] } } } } } } } } ])

Patio de juegos


La segunda versión, puede hacer el proceso etapa por etapa,

  • $match tus condiciones
  • $filter para iterar el bucle de matriz de containers y filtrar por id
  • $arrayElemAt para seleccionar el primer elemento del resultado filtrado anterior
  • $filter para iterar el bucle de la matriz allItems y filtrar elementos por elementos selectedItems
  • $$REMOVE eliminará campos
 db.collection.aggregate([ { $match: { "containers.id": "container1" } }, { $addFields: { containers: "$$REMOVE", container: { $arrayElemAt: [ { $filter: { input: "$containers", cond: { $eq: ["$$this.id", "container1"] } } }, 0 ] } } }, { $addFields: { allItems: "$$REMOVE", "container.selectedItems": { $filter: { input: "$allItems", cond: { $in: ["$$this.id", "$container.selectedItems"] } } } } } ])

Patio de juegos

about 4 years ago · Juan Pablo Isaza Relatório

0

Tienes razón al no necesitar usar $lookup , una serie de expresiones $map y $filter es todo lo que necesitas.

El enfoque es simple, comenzamos filtrando el contenedor requerido, luego iteramos sobre los elementos seleccionados del contenedor selectedItems usando $map y hacemos coincidir los campos relevantes para cada elemento del campo allItems .

 { $match: { id: 1, } }, { $project: { name: 1, container: { "$arrayElemAt": [ { $map: { input: { $filter: { input: "$containers", as: "container", cond: { $eq: [ "$$container.id", "container1" ] } }, }, as: "container", in: { "$mergeObjects": [ { id: "$$container.id" }, { selectedItems: { $map: { input: "$$container.selectedItems", as: "item", in: { "$arrayElemAt": [ { $filter: { input: "$allItems", as: "filter", cond: { $eq: [ "$$filter.id", "$$item" ] } } }, 0 ] } } } } ] } } }, 0 ] } } } ])

Parque infantil Mongo

about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda