MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

MongoDB compte agrégé des éléments dans deux tableaux sur différents documents ?

Oui, c'est un peu plus difficile étant donné qu'il existe plusieurs tableaux, et si vous essayez les deux en même temps, vous vous retrouvez avec une "condition cartésienne" où un tableau multiplie le contenu de l'autre.

Par conséquent, combinez simplement le contenu du tableau au début, ce qui indique probablement comment vous devriez stocker les données en premier lieu :

Model.aggregate(
    [
        { "$project": {
            "company": 1,
            "model": 1,
            "data": {
                "$setUnion": [
                    { "$map": {
                        "input": "$pros",
                        "as": "pro",
                        "in": {
                            "type": { "$literal": "pro" },
                            "value": "$$pro"
                        }
                    }},
                    { "$map": {
                        "input": "$cons",
                        "as": "con",
                        "in": {
                            "type": { "$literal": "con" },
                            "value": "$$con"
                        }
                    }}
                ]
            }
        }},
        { "$unwind": "$data" }
        { "$group": {
            "_id": { 
                "company": "$company",
                "model": "$model",
                "tag": "$data.value"
            },
            "pros": { 
                "$sum": { 
                    "$cond": [
                        { "$eq": [ "$data.type", "pro" ] },
                        1,
                        0
                    ]
                }
            },
            "cons": { 
                "$sum": { 
                    "$cond": [
                        { "$eq": [ "$data.type", "con" ] },
                        1,
                        0
                    ]
                }
            }
        }
    ], 
    function(err,result) {

    }
)

Donc via le premier $project mettre en scène le $map les opérateurs ajoutent la valeur "type" à chaque élément de chaque tableau. Pas que cela importe vraiment ici car tous les éléments doivent de toute façon traiter "unique", le $setUnion l'opérateur "contatene" chaque tableau dans un tableau singulier.

Comme mentionné précédemment, vous devriez probablement stocker de cette manière en premier lieu.

Ensuite, traitez $unwind suivi de $group , où chaque "pour" et "contre" est ensuite évalué via $cond à car il correspond à "type", soit en renvoyant 1 ou 0 où la correspondance est respectivement true/false au $sum accumulateur d'agrégation.

Cela vous donne une "correspondance logique" pour compter chaque "type" respectif dans l'opération d'agrégation selon les clés de regroupement spécifiées.