MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

$ proiezione vs $ elemMatch

La differenza nell'utilizzo della proiezione è alquanto sottile. Nel tuo esempio di utilizzo, queste dovrebbero essere query equivalenti (in termini di utilizzo dell'indice) ma il $elemMatch esempio ripete inutilmente i criteri della query. Il $ la proiezione sarebbe una scelta più sensata per questo esempio.

Una differenza essenziale rilevata nella documentazione è l'array limitazione del campo per $ proiezioni:

Alcune ulteriori note sulle differenze negli operatori di proiezione di seguito ...

Il posizionale ($ ) operatore di proiezione :

  • limita il contenuto di un campo matrice incluso nei risultati della query in modo che contenga il primo elemento che corrisponde al documento della query.

  • richiede che il campo della matrice corrispondente sia incluso nei criteri della query

  • può essere utilizzato solo se nei criteri della query viene visualizzato un singolo campo dell'array

  • può essere utilizzato solo una volta in una proiezione

Il $elemMatch operatore di proiezione

  • limita il contenuto di un campo dell'array incluso nei risultati della query in modo che contenga solo il primo elemento dell'array che corrisponde alla condizione $elemMatch .

  • non richiede che l'array corrispondente sia nei criteri della query

  • può essere utilizzato per soddisfare più condizioni per gli elementi dell'array che sono documenti incorporati

Il $elemMatch operatore di query

Nota che c'è anche un $elemMatch operatore di query che esegue una corrispondenza simile, ma nella query anziché nella proiezione dei risultati. Non è raro vederlo usato in combinazione con un $ proiezione.

Prendere in prestito un esempio dai documenti dove potresti usare entrambi:

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 }
)