MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

Ist es möglich, die Abfrageprojektion für dieselbe Sammlung zu verwenden, die eine $elemMatch-Projektion hat?

Ja, es gibt zwei Möglichkeiten, dies zu tun. Sie können also entweder den $elemMatch auf der Projektionsseite, wie Sie es bereits haben, mit geringfügigen Änderungen:

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

Oder fügen Sie einfach den Abfrageteil hinzu und verwenden Sie den Positionscode $ Betreiber:

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

So oder so ist vollkommen gültig.

Wenn Sie etwas komplizierteres möchten, können Sie den .aggregate() -Methode und es ist $project Operator stattdessen:

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

Das Aggregations-Framework kann also für viel mehr als nur das Aggregieren von Ergebnissen verwendet werden. Es ist $project -Operator gibt Ihnen mehr Flexibilität als die Projektion mit .find() . Außerdem können Sie mehrere Array-Ergebnisse filtern und zurückgeben, was mit der Projektion in .find() ebenfalls nicht möglich ist .