sql >> Database teknologi >  >> NoSQL >> MongoDB

Sådan bruger du $in eller $nin i mongo-aggregation $group $cond

Sammenligningen på $setIsSubset er en kortere mulighed end $or tilstand, du bruger, selvom det stadig er grundlæggende gyldigt at gøre, hvad du gør.

Den eneste fangst med $setIsSubset er, at hvert argument er et array, så du skal konvertere det enkelte element til et enkelt element array. Dette er nemt nok ved at bruge $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
                ]
            }
        }
    }}    
])

Eller hvis du foretrækker det, så match i stedet rækken af ​​argumenter mod entalsværdien med $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
                ]
            }
        }
    }}
])

Hvor $map er snarere at krydse argumenterne for at matche med ental i stedet for at tvinge ental ind i en matrix.

Og selvfølgelig da begge former i det væsentlige leverer true/false til $cond så kan du bare vende logikken med $not hvor det kræves:

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

Det afhænger virkelig af, hvordan du ser på det, men blot som de leverede argumenter, så vinder du ikke rigtig noget over den oprindelige form med $or . Det ser måske lidt renere og "lettere at skrive", men typisk ville jeg ikke "skrive" sådan logik direkte ind i aggregeringspipelinen, men snarere generere den del af strukturen baseret på en almindelig liste i første omgang:

dvs.

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

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

Og så bare ved at bruge det re-mappede matrixindhold i pipelinedefinitionen:

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

Uanset hvordan du ser på det, så husk, at det hele kun er datastrukturer, og du har grundlæggende processer til at manipulere. Både inde i rørledningsbehandlingen og også i selve rørledningskonstruktionen.



  1. Hvordan indstiller jeg standardværdien for et heltal i mongodb?

  2. Gendan fra afbrudt forbindelse i redis pub/sub

  3. Opretter forbindelse til Meteor Mongo fra GUI

  4. Mongodb type referenceknude