sql >> Databasteknik >  >> NoSQL >> MongoDB

MongoDB:Att räkna hur många objekt med ett givet värde som finns i en array, det är i ett dokument?

Aggregeringsramverket är idealiskt för sådana. Överväg att köra följande pipeline för att få önskat resultat.

pipeline = [
    {
        "$match": {
            "name": "james",
            "books.year": 1990
        }
    },
    {
        "$project": {
            "numberOfBooks": {
                "$size": {                  
                    "$filter": {
                        "input": "$books",
                        "as": "el",
                        "cond": { "$eq": [ "$$el.year", 1990 ] }
                    }                   
                }
            }
        }
    }
];
db.collection.pipeline(pipeline);

Ovanstående pipeline använder det nya $filter operatör tillgänglig för MongoDB 3.2 för att producera en array som uppfyller det specificerade villkoret, dvs den filtrerar yttre element som inte uppfyller kriterierna. Den initiala $match pipeline är nödvändig för att filtrera bort dokument som kommer in i aggregeringspipelinen tidigt som en pipelineoptimeringsstrategi.

$size operatorn som accepterar ett enstaka uttryck som argument ger dig sedan antalet element i den resulterande arrayen, så att du har önskat bokantal.

För en alternativ lösning som inte använder $ filter operatör som inte hittades i tidigare versioner, överväg följande pipelineoperation:

pipeline = [
    {
        "$match": {
            "name": "james",
            "books.year": 1990
        }
    },
    {
        "$project": {
            "numberOfBooks": {
                "$size": {                  
                    "$setDifference": [
                        {
                            "$map": {
                                "input": "$books",
                                "as": "el",
                                "in": {
                                    "$cond": [
                                        { "$eq": [ "$$el.year", 1990 ] },
                                        "$$el",
                                        false
                                    ]
                                }
                            }
                        },
                        [false]
                    ]                   
                }
            }
        }
    }
];
db.collection.pipeline(pipeline);

$project pipeline-stadiet innebär att man anpassar bokarrayen så att man tar bort de dokument som inte har årtalet 1990. Detta görs möjligt genom $setDifference och $map operatörer.

$map Operatören skapar i huvudsak ett nytt arrayfält som innehåller värden som ett resultat av den utvärderade logiken i ett underuttryck till varje element i en array. $setDifference operatorn returnerar sedan en uppsättning med element som förekommer i den första uppsättningen men inte i den andra uppsättningen; dvs. utför ett relativt komplement av den andra uppsättningen relativt den första. I det här fallet kommer den att returnera den slutliga bokarrayen som har element med år 1990 och därefter $size beräknar antalet element i den resulterande arrayen, vilket ger dig bokantalet.

För en lösning som använder $avslappnade operatör, med tanke på att (tack vare detta insiktsfulla svar från @BlakesSeven i kommentarerna):

och som en sista utväg, kör följande pipeline:

pipeline = [
    {
        "$match": {
            "name": "james",
            "books.year": 1990
        }
    },
    { "$unwind": "$books" },
    {
        "$match": { "books.year": 1990 }
    },
    {
        "$group": {
            "_id": null
            "count": { "$sum": 1 }
        }
    }
]
db.collection.pipeline(pipeline)


  1. Aggregation i Golang mgo för Mongodb

  2. Hur applicerar man interna sorteringsfält i MongoDb?

  3. Elasticsearch timeout vid varje sökförfrågan tills omstart

  4. Förman slutar omedelbart