• Jobs
  • About Us
  • professionals
    • Home
    • Jobs
    • Courses and challenges
  • business
    • Home
    • Post vacancy
    • Our process
    • Pricing
    • Assessments
    • Payroll
    • Blog
    • Sales
    • Salary Calculator

0

223
Views
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 3 years ago · Santiago Trujillo
1 answers
Answer question

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 3 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Our process Sales
Legal
Terms and conditions Privacy policy
© 2025 PeakU Inc. All Rights Reserved.

Andres GPT

Recommend me some offers
I have an error