sql >> Databáze >  >> NoSQL >> MongoDB

Mongoose vyberte pole subdoc

MongoDB takto zpracovává základní projekci s prvky pole. Zatímco můžete udělat něco takového:

Model.findOne({}, { "comments.upvotes": 1 },function(err,doc) {

})

A to by jen vrátilo pole "upvotes" z dílčích dokumentů pole komentářů pro všechny dokumenty odpovídající podmínce a všechny prvky pole, samozřejmě, nemůžete to kombinovat s vybranou polohovou projekcí pomocí poziční $ operátor. To v podstatě vyplývá z "teorie" to obecně vlastně chcete vrátit celé pole. Takže takhle to vždy fungovalo a není pravděpodobné, že se to brzy změní.

Abyste získali to, co chcete, potřebujete rozšířené možnosti pro manipulaci s dokumenty, které nabízí rámec agregace . To vám dává větší kontrolu nad tím, jak jsou dokumenty vráceny:

Model.aggregate(
    [
        // Match the document containing the array element
        { "$match": { "comments._id" : oid } },

        // Unwind to "de-normalize" the array content
        { "$unwind": "$comments" },

        // Match the specific array element
        { "$match": { "comments._id" : oid } },

        // Group back and just return the "upvotes" field
        { "$group": {
            "_id": "$_id",
            "comments": { "$push": { "upvotes": "$comments.upvotes" } }
        }}
    ],
    function(err,docs) {


    }
);

Nebo v moderních verzích MongoDB od 2.6 můžete dokonce udělat toto:

Model.aggregate(
    [
        { "$match": { "comments._id" : oid } },
        { "$project": {
            "comments": {
                "$setDifference": [
                    { "$map": {
                        "input": "$comments",
                        "as": "el",
                        "in": {
                            "$cond": [
                                { "$eq": [ "$$el._id", oid ] },
                                { "upvotes": "$$el.upvotes" },
                                false
                            ]
                        }
                    }},
                    [false]
                ]
            }}
        }}
    ],
    function(err,docs) {

    }
)

A to používá $map a $setDifference operátory, aby provedli „in-line“ filtrování obsahu pole bez předchozího zpracování $unwind fázi.

Pokud tedy chcete větší kontrolu nad tím, jak se dokument vrací, pak agregační rámec je způsob, jak toho dosáhnout při práci s vloženými dokumenty.




  1. Rady ohledně migrace z MongoMapper na Mongoid?

  2. Integrace Power BI s Spring Angular

  3. Nevýhoda výkonu při použití slugu jako primárního klíče/_id v mongo?

  4. PostgreSQL a MongoDB WHERE v podmínkách