Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

174
Views
Inserción masiva solo cuando se cumple la condición especificada

Tengo una serie de objetos que se ven así:

 { type: 'foo', value : 2, hashedIdentifier : ASDZXC, createdAt : '2022-02-27T14:17:44.860+00:00' }

Me gustaría insertarlos a granel en una colección de MongoDB. Mi lógica comercial exige que no se creen 2 objetos idénticos en un período de 7 días. Para eso, uso el campo hashedIdentifier para encontrar duplicados, donde createdAt es $gte "hace 7 días", filtro los duplicados de la matriz y luego inserto lo que queda en la matriz.

Estas son 2 consultas DB diferentes, y estoy buscando algo un poco más hermético y atómico.

Estaba mirando updateMany con upsert, pero no pude resolver esto.

¿Hay alguna manera de insertar todos los objetos de la matriz de forma masiva, insertando solo aquellos objetos que no entren en conflicto con la restricción anterior (identificador + rango createdAt)?

  • Un índice único (o único compuesto) no me sirve aquí, ya que quiero habilitar la creación de duplicados después de que haya pasado el intervalo de tiempo (7 días).
  • un TTL en objetos de colección también está fuera de discusión, ya que quiero conservarlos todos, para siempre.
over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

Una forma de hacerlo es usar una canalización de agregación con $merge . Por ejemplo:

 db.collection.aggregate([ { $group: { _id: "$hashedIdentifier", latestExisting: { $max: "$createdAt" } } }, { $match: { _id: { $in: [ "ASDZXC", "TSSGKE", "SDFKAR" ] } } }, { $group: { _id: 0, existing: { $push: { hashedIdentifier: "$_id", latestExisting: "$latestExisting" } } } }, { $addFields: { newItems: [ { type: "foo", value: 2, hashedIdentifier: "ASDZXC", createdAt: ISODate("2022-03-06T14:18:44.860+00:00") }, { type: "bar", value: 3, hashedIdentifier: "TSSGKE", createdAt: ISODate("2022-03-06T15:17:44.860+00:00") }, { type: "newOne", value: 9, hashedIdentifier: "SDFKAR", createdAt: ISODate("2022-03-06T15:17:44.860+00:00") } ] } }, { $unwind: "$newItems" }, { $project: { existing: { $filter: { input: "$existing", as: "item", cond: { $eq: [ "$$item.hashedIdentifier", "$newItems.hashedIdentifier" ] } } }, newItems: 1, latestExisting: 1 } }, { $project: { existing: {$arrayElemAt: ["$existing", 0]}, newItem: "$newItems" } }, { $project: { delta: { $subtract: [ "$newItem.createdAt", "$existing.latestExisting" ] }, latestExisting: 1, newItem: 1 } }, { $match: { $or: [{ delta: {$gte: 604800000}}, {delta: null}] } }, { $replaceRoot: {newRoot: "$newItem"} }, { $merge: {into: "collection"} } ])

Como puede ver en este ejemplo de patio de recreo.

Primero, agrupamos los documentos existentes por hashedIdentifier , ya que solo nos interesa la última fecha existente. Luego mantenemos los documentos relevantes que coinciden con los que probamos para insertar y los agrupamos en un solo documento. El siguiente paso es agregar todos los elementos nuevos usando $addFields y $unwind , para que sean documentos separados. Ahora solo tenemos que hacer coincidir para cada elemento nuevo, el elemento existente si hay alguno, y probar la condición de diferencia de tiempo (604800000 ms). Los documentos que coinciden con esta condición se pueden $merge de nuevo en la colección como nuevos documentos validados.

over 4 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 Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!