sql >> Base de Datos >  >> NoSQL >> MongoDB

$proyección vs $elemMatch

La diferencia en el uso de la proyección es algo sutil. En su uso de ejemplo, estas deberían ser consultas equivalentes (en términos de uso de índice) pero el $elemMatch El ejemplo repite innecesariamente los criterios de consulta. El $ proyección sería una opción más sensata para este ejemplo.

Una diferencia esencial observada en la documentación es la matriz limitación de campo para $ proyecciones:

Algunas notas adicionales sobre las diferencias en los operadores de proyección a continuación...

El posicional ($ ) operador de proyección :

  • limita el contenido de un campo de matriz que se incluye en los resultados de la consulta para que contenga el primer elemento que coincida con el documento de consulta.

  • requiere que el campo de matriz coincidente se incluya en los criterios de consulta

  • solo se puede usar si aparece un solo campo de matriz en los criterios de consulta

  • solo se puede usar una vez en una proyección

El $elemMatch operador de proyección

  • limita el contenido de un campo de matriz que se incluye en los resultados de la consulta para que contenga solo el primer elemento de matriz que coincida con la condición $elemMatch .

  • no requiere que la matriz coincidente esté en los criterios de consulta

  • se puede usar para hacer coincidir múltiples condiciones para elementos de matriz que son documentos incrustados

El $elemMatch operador de consulta

Tenga en cuenta que también hay un $elemMatch operador de consulta que realiza una coincidencia similar, pero en la consulta en lugar de la proyección de resultados. No es raro ver esto usado en combinación con un $ proyección.

Tomando prestado un ejemplo de los documentos donde podrías usar ambos:

db.students.find(
    // use $elemMatch query operator to match multiple criteria in the grades array
    { grades: {
        $elemMatch: {
            mean:  { $gt: 70 },
            grade: { $gt: 90 }
        }
    }},

    // use $ projection to get the first matching item in the "grades" array
    { "grades.$": 1 }
)