MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

Mongodb conta todos os elementos da matriz em todos os objetos correspondentes por critérios


A maneira mais "funcional" de fazer isso é pular o $unwind completamente e simplesmente $group contar. Essencialmente, matrizes de "filtro" obtêm o $size dos resultados para $sum :
db.objects.aggregate([
    { "$match": {
        "createddate": {
            "$gte": ISODate("2015-08-30T00:00:00.000Z")
        },
        "activity.action": "test_action"
    }},
    { "$group": {
        "_id": null,
        "count": {
            "$sum": {
                "$size": {
                    "$setDifference": [
                        { "$map": {
                            "input": "$activity",
                            "as": "el",
                            "in": {
                                "$cond": [ 
                                    { "$eq": [ "$$el.action", "test_action" ] },
                                    "$$el",
                                    false
                                ]
                            }               
                        }},
                        [false]
                    ]
                }
            }
        }
    }}
])

Versões futuras do MongoDB terão $filter , o que torna isso muito mais simples:
db.objects.aggregate([
    { "$match": {
        "createddate": {
            "$gte": ISODate("2015-08-30T00:00:00.000Z")
        },
        "activity.action": "test_action"
    }},
    { "$group": {
        "_id": null,
        "count": {
            "$sum": {
                "$size": {
                    "$filter": {
                        "input": "$activity",
                        "as": "el",
                        "cond": {
                            "$eq": [ "$$el.action", "test_action" ]
                        }
                    }
                }
            }
        }
    }}
])

Usando $unwind faz com que os documentos sejam desnormalizados e cria efetivamente uma cópia por entrada de matriz. Sempre que possível, você deve evitar isso devido ao custo muitas vezes extremo. Filtrar e contar entradas de matriz por documento é muito mais rápido em comparação. Assim como um simples $match e $group pipeline em comparação com muitos estágios.