Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

264
Vistas
Alterar un solo objeto anidado dentro de una matriz

Lo que debo hacer es actualizar los contadores dentro del único objeto anidado o insertar el documento completo que contiene la matriz con contadores iniciados.

Ejemplo de documento:

 { "_id":{"$oid":"61f020f40e2f03f0b93b69f1"}, "v":"xxxxxxxxxxxxxxxx", "list":[{"p":{"$oid":"61f020f40e2f03f0b93b69f0"},"c":1,"hom":0,"het":1}] }

Todos los documentos tendrán con seguridad una matriz de "lista" con al menos y como máximo un objeto anidado. Y el par (v,list.p) es único.

Entonces, a partir de una búsqueda anterior, para cada elemento del cursor, estoy llamando a la función upsert en js, que en realidad encuentra el documento, luego inserta o actualiza la colección si se encuentra.

 function upsert(doc){ _hom = doc.field1.field2 == "hom" ? 1 : 0; _het = doc.field1.field2 == "het" ? 1 : 0; filter = {"v": doc.anId, "list.p" : "61f020f40e2f03f0b93b69f0"}; project = {"list.c":1, "list.hom":1, "list.het":1, "_id":0}; res = db.collection.find(filter, project); if(!res.hasNext()){ doc = {"v": doc.anId, "list" : [{"p" : "61f020f40e2f03f0b93b69f0", "c" : 1, "hom" : _hom, "het" : _het}]} db.collection.insertOne(doc) } else { list = res.next().list[0]; _c = list.c + 1; _hom += list.hom; _het += list.het; update = {$set : {"list" : [{"p" : "61f020f40e2f03f0b93b69f0", "c" : _c, "hom" : _hom, "het" : _het}]}} db.collection.updateOne(filter, update) } }

Así que imagina algo como:

 db.anotherCollection.find({...},{...}).forEach(doc => upsert(doc))

Funciona, pero es bastante lento. Hay alguna otra manera de hacer esto? Leí en línea que no es posible alterar una matriz para hacer algo como esto, porque necesita empujar, tirar, según la consulta, etc. Pero necesito actualizar los contadores existentes de un objeto anidado, si se encuentra doc, o más bien inserte un documento completo, si no se encuentra el documento.

Mongo 4.4.6

over 4 years ago · Santiago Trujillo
1 Respuestas
Responde la pregunta

0

Por lo tanto, esto realmente no se puede hacer en una sola llamada a la base de datos; sin embargo, podría simplificar el código y reducir la cantidad promedio de llamadas a la base de datos realizadas en total.

Específicamente hablando, podemos en lugar de find -> update simplemente ejecutar una actualización, si la actualización es "exitosa", entonces podemos regresar, de lo contrario insertamos. Esto significa que cada vez que la list ya existe, tiene una consulta de find redundante que no es necesaria.

Aquí está el código:

 function upsert(doc){ _hom = doc.field1.field2 == "hom" ? 1 : 0; _het = doc.field1.field2 == "het" ? 1 : 0; filter = {"v": doc.anId, "list.p" : "61f020f40e2f03f0b93b69f0"}; update = {$inc : {"list.$.c": 1}} updateRes = db.collection.updateOne(filter, update) if(updateRes.matchedCount == 0){ doc = {"v": doc.anId, "list" : [{"p" : "61f020f40e2f03f0b93b69f0", "c" : 1, "hom" : _hom, "het" : _het}]} db.collection.insertOne(doc) } }

Ahora, la cantidad de rendimiento mejorado depende de su tasa de "aciertos", supongo que para la mayoría de los procesos debería ser alta, lo que significa que será significativa. El rendimiento de los "errores" no se ve afectado ya que la actualización "actúa" igual que una búsqueda si no existe un documento coincidente.

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda