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

888
Views
MongoDb $ elemMatch con $ variable de búsqueda

Tengo una colección determinada de MongoDb con documentos que se parecen a esto:

 { items: [ { id: 1, data: 'a' }, { id: 2, data: 'b' }, { id: 3, data: 'c' }, ] }

Ahora tengo que $lookup en esta colección. Necesito los datos de la matriz del elemento con id = 2 donde id = 1 data coincide con el valor de búsqueda $$value . Mi primer intento ingenuo de encontrar el documento correcto se veía así:

 $match { items: { $elemMatch: { id: 1, data: '$$value' } } }

Pero el $$value no se evalúa, por lo que los datos se comparan con el literal en lugar de su valor. También traté de evaluar el valor usando $expr , pero no pude obtener la sintaxis correcta (¿si es posible?).

La única forma de trabajo en la que pude trabajar fue extrayendo los datos primero y luego haciendo la comparación:

 [ { $project: { _id: 0, data1: { $filter: { input: '$items', as: 'item', cond: {$eq: ['$$item.id', 1]} } }, data2: { $filter: { input: '$items', as: 'item', cond: {$eq: ['$$item.id', 2]} } }, } }, { $set: { data1: {$arrayElemAt: ['$data1.data', 0]}, data2: {$arrayElemAt: ['$data2.data', 0]} } }, { $match: { $expr: {$eq: ['$data1', '$$value']} } } ];

Pero como era de esperar, este enfoque es mucho más lento. Para los datos involucrados, la consulta tomó más de 7 segundos, mientras que el enfoque superior (usando una constante en lugar de una variable $$value ) fue tres veces más rápido.

¿Es posible usar la variable $$value directamente en el operador $elemMatch ? ¿O hay alguna otra optimización disponible para acelerar la búsqueda de colecciones?

over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

Entonces, primero entendamos por qué falló su enfoque ingenuo, los documentos de búsqueda canalizados de Mongo especifican que:

Una etapa $match requiere el uso de un operador $expr para acceder a las variables. $expr permite el uso de expresiones de agregación dentro de la sintaxis de $match.

Por lo tanto, solo se puede acceder al value de la variable que está definiendo al comienzo de la $lookup con el uso de $expr , ahora también especificado en los documentos de $expr :

Los argumentos pueden ser cualquier expresión de agregación válida

Lamentablemente para nosotros, $elemMatch no es una "expresión de agregación", ya que pertenece al "lenguaje de consulta". es por eso que tu primer enfoque falló. Simplemente no puede usar $elemMatch dentro de una $expr que se requiere para acceder al campo $$value .

Entonces, ¿qué podemos hacer? Bueno, puedes usar $filter como ya empezaste a hacer:

 db.collection.aggregate([ { $lookup: { from: "collection2", let: { value: "$data" }, pipeline: [ { $match: { $expr: { $gt: [ { $size: { $filter: { input: "$items", as: "item", cond: { $and: [ { $eq: [ "$$item.id", 1 ] }, { $eq: [ "$$item.data", "$$value" ] } ] } } } }, 0 ], } } } ], as: "res" } } ])

Sería más fácil responder completamente si proporciona la estructura completa de ambas colecciones y el resultado final requerido, ya que tuve que adivinar algunas de las cosas aquí para escribir esta canalización.

Parque infantil Mongo

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!