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

MongoDB:Počítání, kolik položek s danou hodnotou existuje v poli, to je v dokumentu?

Agregační rámec je pro to ideální. Zvažte spuštění následujícího kanálu, abyste získali požadovaný výsledek.

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

Výše uvedený kanál používá nový $filter operátor dostupný pro MongoDB 3.2 k vytvoření pole, které splňuje zadanou podmínku, tj. filtruje vnější prvky, které nesplňují kritéria. Počáteční $match kanál je nezbytný k odfiltrování dokumentů, které se dostanou do agregačního kanálu v rané fázi jako strategie optimalizace kanálu.

velikost $ operátor, který akceptuje jeden výraz jako argument, vám pak dá počet prvků ve výsledném poli, takže máte požadovaný počet knih.

Pro alternativní řešení, které nepoužívá $ filtr operátor nenalezený v dřívějších verzích, zvažte následující operaci kanálu:

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 fáze potrubí zahrnuje přizpůsobení pole knih tak, že odstraníte dokumenty, které nemají rok 1990. To je možné prostřednictvím $setDifference a $map operátory.

$map operátor v podstatě vytvoří nové pole pole, které obsahuje hodnoty jako výsledek vyhodnocené logiky v podvýrazu ke každému prvku pole. $setDifference operátor pak vrátí sadu s prvky, které se vyskytují v první sadě, ale ne ve druhé sadě; tj. provádí relativní doplněk druhé sady vzhledem k první. V tomto případě vrátí konečné pole knih, které má prvky s rokem 1990 a následně $size vypočítá počet prvků ve výsledném poli, čímž získáte počet knih.

Pro řešení, které používá $unwind operátora, mějte na paměti, že (díky této zasvěcené odpovědi od @BlakesSeven v komentářích):

a jako poslední možnost spusťte následující kanál:

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


  1. Mongodb:Pokud je podmínka splněna, vloží prvek do vnořeného pole

  2. MongoDB běží celkem jako agregace předchozích záznamů až do výskytu hodnoty

  3. Redis vs. Memcached – srovnání roku 2021

  4. Jak dynamicky $nastavit pole vnořeného dokumentu v mongodb?