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

Mongodb compte tous les éléments du tableau dans tous les objets correspondant aux critères

La façon la plus "performante" de le faire est d'ignorer le $unwind en tout et simplement $group compter. Essentiellement, les tableaux de "filtre" obtiennent la $size des résultats à $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]
                    ]
                }
            }
        }
    }}
])

Les futures versions de MongoDB auront $filter , ce qui rend cela beaucoup plus simple :

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" ]
                        }
                    }
                }
            }
        }
    }}
])

Utiliser $unwind provoque la dénormalisation des documents et crée effectivement une copie par entrée de tableau. Dans la mesure du possible, vous devriez éviter cela en raison du coût souvent extrême. Le filtrage et le comptage des entrées de tableau par document sont beaucoup plus rapides en comparaison. Comme un simple $match et $group pipeline par rapport à de nombreuses étapes.