sql >> Databasteknik >  >> NoSQL >> MongoDB

MongoDB:Aggregation med $cond med $regex

UPPDATERING: Från och med MongoDB v4.1.11 verkar det äntligen finnas en bra lösning för ditt problem som är dokumenterad här .

Ursprungligt svar:

Som jag skrev i kommentarerna ovan, $regex fungerar inte i $cond från och med nu. Det finns en öppen JIRA-biljett för det men det är, err, ja, öppet...

I ditt specifika fall skulle jag vilja föreslå att du löser det ämnet på klientsidan om du inte har att göra med galna mängder indata som du alltid bara kommer att returnera små delmängder av. Att döma av din fråga verkar det som om du alltid kommer att hämta alla dokument som just är placerade i två resultatgrupper ("Ja" och "Nej").

Om du inte vill eller inte kan lösa det ämnet på klientsidan, så här är något som använder $facet (MongoDB>=v3.4 krävs) - det är varken särskilt snabbt eller överdrivet snyggt men det kan hjälpa dig att komma igång.

db.captions.aggregate([{
    $facet: { // create two stages that will be processed using the full input data set from the "captions" collection
        "CallToActionYes": [{ // the first stage will...
            $match: { // only contain documents...
                "plainText": /leave\sa\scomment/i // that are allowed by the $regex filter (which could be extended with multiple $or expressions or changed to $in/$nin which accept regular expressions, too)
            }
        }, {
            $addFields: { // for all matching documents...
                "CallToAction": "Yes" // we create a new field called "CallsToAction" which will be set to "Yes"
            }
        }],
        "CallToActionNo": [{ // similar as above except we're doing the inverse filter using $not
            $match: {
                "plainText": { $not: /leave\sa\scomment/i }
            }
        }, {
            $addFields: {
                "CallToAction": "No" // and, of course, we set the field to "No"
            }
        }]
    }
}, {
    $project: { // we got two arrays of result documents out of the previous stage
        "allDocuments" : { $setUnion: [ "$CallToActionYes", "$CallToActionNo" ] } // so let's merge them into a single one called "allDocuments"
    }
}, {
    $unwind: "$allDocuments" // flatten the "allDocuments" result array
}, {
    $replaceRoot: { // restore the original document structure by moving everything inside "allDocuments" up to the top
        newRoot: "$allDocuments"
    }
}, {
    $project: { // include only the two relevant fields in the output (and the _id)
        "videoId": 1,
        "CallToAction": 1
    }
}])

Som alltid med aggregeringsramverket kan det hjälpa att ta bort enskilda steg från slutet av pipelinen och köra delfrågan för att få en förståelse för vad varje enskilt steg gör.




  1. Bästa sättet att gruppera efter datum med Mongoid

  2. Mongoose - åtkomst till kapslade objekt med .populate

  3. Fel:getaddriinfo ENOTFOUND i nodejs for get call

  4. Node redis utgivare förbrukar för mycket minne