MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

MongoDB:Агрегиране с помощта на $cond с $regex

АКТУАЛИЗАЦИЯ: Започвайки с 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
    }
}])

Както винаги с рамката за агрегиране, може да помогне премахването на отделни етапи от края на конвейера и изпълнението на частичната заявка, за да разберете какво прави всеки отделен етап.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Съвет за мигриране от MongoMapper към Mongoid?

  2. Направете скрипт за създаване на MongoDB колекции от Mongo shell?

  3. Spring Data Mongo - Как да получа вложения различен масив за вложена стойност?

  4. Грешка при връзка с Mongodb въпреки докера в springboot

  5. Разгръщане и конфигуриране на MongoDB Shards с Ansible