sql >> Base de Datos >  >> NoSQL >> MongoDB

MongoDB cuenta agregada de elementos en dos matrices en diferentes documentos?

Sí, esto es un poco más difícil teniendo en cuenta que hay varios arreglos, y si prueba ambos al mismo tiempo, termina con una "condición cartesiana" en la que un arreglo multiplica el contenido del otro.

Por lo tanto, simplemente combine el contenido de la matriz al principio, lo que probablemente indica cómo debería almacenar los datos en primer lugar:

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

    }
)

Entonces, a través del primer $project organizar el $map los operadores están agregando el valor de "tipo" a cada elemento de cada matriz. No es que realmente importe aquí, ya que todos los elementos deben procesarse como "únicos" de todos modos, el $setUnion operador "contatena" cada arreglo en un arreglo singular.

Como se mencionó anteriormente, probablemente debería almacenar de esta manera en primer lugar.

Luego procesa $unwind seguido de $group , donde cada "pros" y "contras" se evalúa a través de $cond a por su "tipo" coincidente, ya sea devolviendo 1 o 0 donde la coincidencia es respectivamente true/false al $sum acumulador de agregación.

Esto le da una "coincidencia lógica" para contar cada "tipo" respectivo dentro de la operación de agregación según las claves de agrupación especificadas.