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

MongoDB:Aggregation ved hjælp af $cond med $regex

OPDATERING: Startende med MongoDB v4.1.11 ser der endelig ud til at være en god løsning på dit problem, som er dokumenteret her .

Oprindeligt svar:

Som jeg skrev i kommentarerne ovenfor, $regex virker ikke i $cond fra nu af. Der er en åben JIRA-billet for det, men det er, err, nå, åbent...

I dit specifikke tilfælde vil jeg være tilbøjelig til at foreslå, at du løser det emne på klientsiden, medmindre du har at gøre med vanvittige mængder inputdata, hvoraf du altid kun vil returnere små delmængder. At dømme efter din forespørgsel ser det ud til, at du altid vil hente alle dokumenter, der lige er inddelt i to resultatgrupper ("Ja" og "Nej").

Hvis du ikke vil eller kan løse det emne på klientsiden, så er her noget, der bruger $facet (MongoDB>=v3.4 påkrævet) - den er hverken særlig hurtig eller overdrevent smuk, men den kan måske hjælpe dig med at komme i gang.

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 altid med aggregeringsrammen kan det hjælpe at fjerne individuelle trin fra slutningen af ​​pipelinen og køre den delvise forespørgsel for at få en forståelse af, hvad hver enkelt fase gør.




  1. make mislykkes ved at prøve at installere mongo php-driver på Centos 6

  2. Mest effektive måde at gemme indlejrede kategorier (eller hierarkiske data) i Mongo?

  3. Indeks eksisterer allerede med forskellige valgmuligheder, mens du bruger createIndex() i den nyeste MongoDB java-driver

  4. På grund af begrænsninger af com.mongodb.BasicDBObject-undtagelsen, når der tilføjes flere kriterier GridFSDBFile-forespørgsel