sql >> Database >  >> NoSQL >> MongoDB

Hoe $in of $nin te gebruiken in mongo-aggregatie $group $cond

De vergelijking op $setIsSubset is een kortere optie dan de $or voorwaarde die u gebruikt, hoewel deze in principe nog steeds geldig is om te doen wat u doet.

De enige vangst met $setIsSubset is dat elk argument een array is, dus je moet het enkele element converteren naar een array met één element. Dit is eenvoudig genoeg met $map :

db.collectionName.aggregate([
    { "$group": {
        "_id": "$createdAt",
        "count": { "$sum": 1 },
        "count_failure": {
            "$sum": {
                "$cond": [
                    { "$setIsSubset": [
                        { "$map": {
                            "input": ["A"],
                            "as": "el",
                            "in": "$id"
                        }},
                        [ 0,100,101,102,103,104,105 ],
                    ]},
                    1,
                    0
                ]
            }
        }
    }}    
])

Of als je wilt, vergelijk dan de reeks argumenten met de enkelvoudige waarde, met $anyElementTrue :

db.collectionName.aggregate([
    { "$group": {
        "_id": "$createdAt",
        "count": { "$sum": 1 },
        "count_failure": {
            "$sum": {
                "$cond": [
                    { "$anyElementTrue": { "$map": {
                        "input": [ 0,100,101,102,103,104,105 ],
                        "as": "el",
                        "in": { "$eq": [ "$$el", "$id" ] }
                    }}},
                    1,
                    0
                ]
            }
        }
    }}
])

Waar de $map doorloopt eerder de argumenten om overeen te komen met het enkelvoud in plaats van het enkelvoud in een array te forceren.

En natuurlijk, aangezien beide vormen in wezen true/false leveren naar de $cond dan kun je de logica gewoon omdraaien met $not waar nodig:

db.collectionName.aggregate([
    { "$group": {
        "_id": "$createdAt",
        "count": { "$sum": 1 },
        "count_failure": {
            "$sum": {
                "$cond": [
                    { "$not": [{ "$anyElementTrue": { "$map": {
                        "input": [ 0,100,101,102,103,104,105 ],
                        "as": "el",
                        "in": { "$eq": [ "$$el", "$id" ] }
                    }}}]},
                    1,
                    0
                ]
            }
        }
    }}
])

Het hangt er echt van af hoe je het bekijkt, maar gewoon als verstrekte argumenten, dan win je niet echt iets boven de originele vorm met $or . Het ziet er misschien een beetje schoner en "gemakkelijker te typen" uit, maar meestal zou ik dergelijke logica niet rechtstreeks in de aggregatiepijplijn "typen", maar eerder dat deel van de structuur genereren op basis van een duidelijke lijst in de eerste plaats:

d.w.z.

var failList = [ 0,100,101,102,103,104,105 ];

var orCondition = failList.map(function(el) { 
    return { "$eq": [ "$id", el ] }
})

En dan gewoon de opnieuw toegewezen array-inhoud in de pijplijndefinitie gebruiken:

    { "$group": {
        "_id": "$createdAt",
        "count": { "$sum": 1 },
        "count_failure": {
            "$sum": {
                "$cond": [
                    { "$or": orCondition },
                    1,
                    0
                ]
            }
        }
    }}
])

Hoe je het ook bekijkt, onthoud dat het allemaal maar datastructuren zijn en dat je basisprocessen hebt om te manipuleren. Zowel binnen de leidingverwerking als ook in de leidingconstructie zelf.



  1. MongoDB - Afdrukken

  2. mongodb:zoek de eerste paar rijen op waarbij de som van een specifieke kolom groter of gelijk is aan C

  3. Hoe maak je verbinding met een replicaset vanuit een MongoDB-shell?

  4. Mongoose / MongoDB:tel elementen in array