АКТУАЛИЗАЦИЯ: Започвайки с MongoDB v4.1.11, най-накрая изглежда има хубаво решение за вашия проблем, което е документирано тук .
Оригинален отговор:
Както написах в коментарите по-горе, $regex
не работи вътре в $cond
от сега. Има отворен билет за JIRA
за това, но е, ъъъ, добре, отворено...
Във вашия конкретен случай бих предложил да разрешите тази тема от страна на клиента, освен ако не се занимавате с луди количества входни данни, от които винаги ще връщате само малки подмножества. Съдейки по вашата заявка, ще изглежда, че винаги ще извличате всички документи, просто групирани в две групи резултати („Да“ и „Не“).
Ако не искате или не можете да разрешите тази тема от страна на клиента, тогава ето нещо, което използва $facet (Изисква се MongoDB>=v3.4) - нито е особено бърз, нито прекалено красив, но може да ви помогне да започнете.
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
}
}])
Както винаги с рамката за агрегиране, може да помогне премахването на отделни етапи от края на конвейера и изпълнението на частичната заявка, за да разберете какво прави всеки отделен етап.