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

¿Es posible usar la proyección de consulta en la misma colección que tiene una proyección $ elemMatch?

Sí, hay dos maneras de hacer esto. Entonces puede usar $elemMatch en el lado de la proyección como ya tienes, con ligeros cambios:

Model.findById(id,
   { "comments": { "$elemMatch": {"created.by": "Jane" } } },
   function(err,doc) {

O simplemente agregue a la parte de consulta y use el $ posicional operador:

Model.findOne(
    { "_id": id, "comments.created.by": "Jane" },
    { "comments.$": 1 },
    function(err,doc) {

Cualquiera de las dos formas es perfectamente válida.

Si quería algo un poco más complicado que eso, puede usar .aggregate() y es $project operador en su lugar:

Model.aggregate([
    // Still match the document
    { "$match": "_id": id, "comments.created.by": "Jane" },

    // Unwind the array
    { "$unwind": "$comments" },

    // Only match elements, there can be more than 1
    { "$match": "_id": id, "comments.created.by": "Jane" },

    // Project only what you want
    { "$project": {
        "comments": {
            "body": "$comments.body",
            "by": "$comments.created.by"
        }
    }},

    // Group back each document with the array if you want to
    { "$group": {
        "_id": "$_id",
        "comments": { "$push": "$comments" }
    }}
],
function(err,result) {

Por lo tanto, el marco de agregación se puede usar para mucho más que simplemente agregar resultados. Es $project El operador le brinda más flexibilidad de la que está disponible para la proyección usando .find() . También le permite filtrar y devolver múltiples resultados de matrices, algo que tampoco se puede hacer con la proyección en .find() .