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

MongoDB skupina a součet s id jako klíčem

S MongoDb 3.6 a novějšími můžete využít použití $arrayToObject operátor a $replaceRoot potrubí k dosažení požadovaného výsledku. Budete muset spustit následující agregační kanál:

db.users.aggregate([
    { 
        "$group": {
            "_id": { "$toLower": "$role" },
            "count": { "$sum": 1 }
        }
    },
    { 
        "$group": {
            "_id": null,
            "counts": {
                "$push": {
                    "k": "$_id",
                    "v": "$count"
                }
            }
        }
    },
    { 
        "$replaceRoot": {
            "newRoot": { "$arrayToObject": "$counts" }
        } 
    }    
])

U starších verzí $cond operátor ve $group krok potrubí lze efektivně použít k vyhodnocení počtů na základě hodnoty pole role. Váš celkový agregační kanál může být zkonstruován následovně, abyste získali výsledek v požadovaném formátu:

db.users.aggregate([    
    { 
        "$group": { 
            "_id": null,             
            "moderator_count": {
                "$sum": {
                    "$cond": [ { "$eq": [ "$role", "moderator" ] }, 1, 0 ]
                }
            },
            "superadmin_count": {
                "$sum": {
                    "$cond": [ { "$eq": [ "$role", "superadmin" ] }, 1, 0 ]
                }
            },
            "user_count": {
                "$sum": {
                    "$cond": [ { "$eq": [ "$role", "user" ] }, 1, 0 ]
                }
            },
            "admin_count": {
                "$sum": {
                    "$cond": [ { "$eq": [ "$role", "admin" ] }, 1, 0 ]
                }
            } 
        }  
    },
    {
        "$project": {
            "_id": 0, 
            "moderator": "$moderator_count",
            "superadmin": "$superadmin_count",
            "user": "$user_count",
            "admin": "$admin_count"
        }
    }
])

Pokud role předem neznáte a chtěli byste vytvořit pole potrubí dynamicky, spusťte distinct příkaz na poli role. Získáte tak objekt, který obsahuje seznam různých rolí:

var result = db.runCommand ( { distinct: "users", key: "role" } )
var roles = result.values;
printjson(roles); // this will print ["moderator", "superadmin", "user",  "admin"]

Nyní s ohledem na výše uvedený seznam můžete sestavit svůj kanál vytvořením objektu, který bude mít své vlastnosti nastavené pomocí reduce() v JavaScriptu metoda. Toto demonstruje následující:

var groupObj = { "_id": null },
    projectObj = { "_id": 0 }

var groupPipeline = roles.reduce(function(obj, role) { // set the group pipeline object 
    obj[role + "_count"] = {
        "$sum": {
            "$cond": [ { "$eq": [ "$role", role ] }, 1, 0 ]
        }
    };
    return obj;
}, groupObj );

var projectPipeline = roles.reduce(function(obj, role) { // set the project pipeline object 
    obj[role] = "$" + role + "_count";
    return obj;
}, projectObj );

Použijte tyto dva dokumenty ve svém konečném agregačním kanálu jako:

db.users.aggregate([groupPipeline, projectPipeline]);

Podívejte se na ukázku níže.

var roles = ["moderator", "superadmin", "user",  "admin"],
	groupObj = { "_id": null },
	projectObj = { "_id": 0 };

var groupPipeline = roles.reduce(function(obj, role) { // set the group pipeline object 
	obj[role + "_count"] = {
		"$sum": {
			"$cond": [ { "$eq": [ "$role", role ] }, 1, 0 ]
		}
	};
	return obj;
}, groupObj );

var projectPipeline = roles.reduce(function(obj, role) { // set the project pipeline object 
	obj[role] = "$" + role + "_count";
	return obj;
}, projectObj );

var pipeline = [groupPipeline, projectPipeline]

pre.innerHTML = JSON.stringify(pipeline, null, 4);
<pre id="pre"></pre>


  1. Jak analyzovat využití disku kontejneru Docker

  2. Monitoring &Ops Management MongoDB 4.0 s ClusterControl

  3. Mongodb Query Výběr záznamů s daným klíčem

  4. Jak omezit počet aktualizací dokumentů v mongodb