更新: MongoDB v4.1.11から、問題の優れた解決策がついに登場しました。これは、に文書化されています。ここ 。
元の回答:
上記のコメントで書いたように、$regex
$cond
内では機能しません 今のところ。オープンな
あなたの特定のケースでは、常に小さなサブセットしか返さないクレイジーな量の入力データを扱っているのでない限り、クライアント側でそのトピックを解決することをお勧めします。クエリから判断すると、2つの結果グループ(「はい」と「いいえ」)にバケット化されたすべてのドキュメントを常に取得するように見えます。
クライアント側でそのトピックを解決したくない、または解決できない場合は、$ファセット (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
}
}])
集計フレームワークの場合と同様に、パイプラインの最後から個々のステージを削除し、部分的なクエリを実行して、個々のステージの機能を理解することが役立つ場合があります。