sql >> Database >  >> NoSQL >> MongoDB

MongoDB:Aggregatie met $cond met $regex

UPDATE: Beginnend met MongoDB v4.1.11, lijkt er eindelijk een mooie oplossing voor uw probleem te zijn die is gedocumenteerd hier .

Oorspronkelijke antwoord:

Zoals ik in de opmerkingen hierboven schreef, $regex werkt niet binnen $cond vanaf nu. Er is een open JIRA-ticket daarvoor, maar het is, eh, nou ja, open...

In jouw specifieke geval zou ik de neiging hebben om dat onderwerp aan de kant van de klant op te lossen, tenzij je te maken hebt met waanzinnige hoeveelheden invoergegevens waarvan je altijd alleen kleine subsets zult retourneren. Afgaande op uw vraag lijkt het alsof u altijd alle documenten ophaalt die zojuist in twee resultaatgroepen zijn ondergebracht ("Ja" en "Nee").

Als je dat onderwerp niet aan de kant van de klant wilt of kunt oplossen, dan is hier iets dat $facet (MongoDB>=v3.4 vereist) - het is niet bijzonder snel of overdreven mooi, maar het kan je misschien helpen om aan de slag te gaan.

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

Zoals altijd bij het aggregatieraamwerk, kan het helpen om afzonderlijke fasen aan het einde van de pijplijn te verwijderen en de gedeeltelijke query uit te voeren om inzicht te krijgen in wat elke afzonderlijke fase doet.




  1. Geneste $addFields in MongoDB

  2. Hoe de logboekregistratie van mongoDB Java-stuurprogramma's uit te schakelen?

  3. Query IDE voor MongoDB?

  4. MongoDB-queryresultaten exporteren naar een CSV-bestand