MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

MongoDB aggregierte Anzahl von Elementen in zwei Arrays über verschiedene Dokumente hinweg?

Ja, das ist etwas schwieriger, wenn man bedenkt, dass es mehrere Arrays gibt, und wenn Sie beide gleichzeitig versuchen, erhalten Sie eine "kartesische Bedingung", bei der ein Array den Inhalt des anderen multipliziert.

Kombinieren Sie daher am Anfang einfach den Array-Inhalt, der wahrscheinlich anzeigt, wie Sie die Daten überhaupt speichern sollten:

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

    }
)

Also über den ersten $project Stellen Sie den $map bereit Operatoren fügen den "Typ"-Wert zu jedem Element jedes Arrays hinzu. Nicht, dass es hier wirklich wichtig wäre, da alle Artikel sowieso "unique" verarbeiten sollten, der $setUnion Operator "verdichtet" jedes Array zu einem einzelnen Array.

Wie bereits erwähnt, sollten Sie wahrscheinlich von Anfang an auf diese Weise speichern.

Dann verarbeiten Sie $unwind gefolgt von $group , wobei jedes „Pro“ und „Contra“ dann über $cond to für den übereinstimmenden "Typ", wobei entweder 1 zurückgegeben wird oder 0 wobei die Übereinstimmung jeweils true/false ist zu $sum Aggregationsakkumulator.

Dadurch erhalten Sie eine „logische Übereinstimmung“, um jeden jeweiligen „Typ“ innerhalb der Aggregationsoperation gemäß den angegebenen Gruppierungsschlüsseln zu zählen.