sql >> Databasteknik >  >> NoSQL >> MongoDB

Hur man använder $in eller $nin i mongo-aggregation $group $cond

Jämförelsen på $setIsSubset är ett kortare alternativ än $or skick du använder, men det är fortfarande i princip giltigt att göra det du gör.

Den enda haken med $setIsSubset är att varje argument är en array så du måste konvertera det enstaka elementet till en enstaka element array. Detta är tillräckligt enkelt med $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 om du föredrar det, matcha sedan argumenten mot singularvärdet istället 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
                ]
            }
        }
    }}
])

Där $map går snarare igenom argumenten för att matcha singularen snarare än att tvinga singularen in i en array.

Och naturligtvis eftersom båda formulären i huvudsak tillhandahåller true/false till $cond då kan du bara vända på logiken med $not vid behov:

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 beror verkligen på hur du ser på det, men helt enkelt som medföljande argument så vinner du egentligen ingenting över den ursprungliga formen med $or . Det kan se lite renare och "lättare att skriva", men vanligtvis skulle jag inte "skriva" sådan logik i aggregeringspipelinen direkt, utan snarare generera den delen av strukturen baserat på en vanlig lista i första hand:

dvs

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

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

Och sedan bara använda det ommappade arrayinnehållet i pipelinedefinitionen:

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

Hur du än ser på det, kom ihåg att det bara är datastrukturer och att du har grundläggande processer för att manipulera. Både inne i rörledningsbearbetningen och även i själva rörledningskonstruktionen.



  1. kan inte hämta data från vinkel http

  2. Utför anpassad funktion på MongoDB med Casbah/Scala

  3. Hur kör man db.killOp() med MongoDBs inbyggda Node.js-drivrutin?

  4. ansluter till Mongodb inuti en dockare med mongodb kompass GUI