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

MongoDB:At tælle hvor mange elementer med en given værdi, der findes i et array, er det i et dokument?

Aggregeringsrammen er ideel til sådanne. Overvej at køre følgende pipeline for at få det ønskede 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);

Ovenstående pipeline bruger det nye $filter operatør tilgængelig for MongoDB 3.2 til at producere et array, der opfylder den specificerede betingelse, dvs. den filtrerer ydre elementer, der ikke opfylder kriterierne. Den indledende $match pipeline er nødvendig for at bortfiltrere dokumenter, der kommer ind i aggregeringspipelinen tidligt som en pipeline-optimeringsstrategi.

$size operator, der accepterer et enkelt udtryk som argument, giver dig derefter antallet af elementer i det resulterende array, så du har dit ønskede bogantal.

For en alternativ løsning, der ikke bruger $ filter operatør ikke fundet i tidligere versioner, overvej følgende pipeline-operation:

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

$projekt pipeline-stadiet indebærer tilpasning af bogarrayet, så du fjerner de dokumenter, der ikke har årstal 1990. Dette er gjort muligt gennem $setDifference og $map operatører.

$map operatoren opretter i det væsentlige et nyt matrixfelt, der indeholder værdier som et resultat af den evaluerede logik i et underudtryk til hvert element i en matrix. $setDifference operator returnerer derefter et sæt med elementer, der vises i det første sæt, men ikke i det andet sæt; dvs. udfører et relativt komplement af det andet sæt i forhold til det første. I dette tilfælde vil det returnere det endelige bogarray, der har elementer med år 1990 og efterfølgende $size beregner antallet af elementer i det resulterende array, hvilket giver dig bogantallet.

For en løsning, der bruger $slap af operatør, med det i tankerne (takket være dette indsigtsfulde svar fra @BlakesSeven i kommentarerne):

og som en sidste udvej skal du køre følgende 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. Kan ikke forbinde Redis Cluster i Elasticache til PHP ved hjælp af phpredis-biblioteket

  2. MongoError:Denne MongoDB-implementering understøtter ikke skrivninger, der kan prøves igen. Tilføj venligst retryWrites=false til din forbindelsesstreng

  3. Begræns listens længde i redis

  4. Hvordan kunne jeg konvertere en bytes til en hel hex-streng?