MongoDB
 sql >> Baza danych >  >> NoSQL >> MongoDB

MongoDB:agregacja za pomocą $cond z $regex

AKTUALIZACJA: Począwszy od MongoDB v4.1.11, wreszcie wydaje się, że istnieje dobre rozwiązanie dla twojego problemu, które jest udokumentowane tutaj .

Oryginalna odpowiedź:

Jak napisałem w komentarzach powyżej, $regex nie działa wewnątrz $cond od teraz. Jest otwarty bilet JIRA za to, ale to jest, eee, cóż, otwarte...

W twoim konkretnym przypadku sugerowałbym rozwiązanie tego tematu po stronie klienta, chyba że masz do czynienia z szaloną ilością danych wejściowych, z których zawsze zwrócisz tylko małe podzbiory. Sądząc po zapytaniu, wygląda na to, że zawsze będziesz pobierać cały dokument podzielony na dwie grupy wyników („Tak” i „Nie”).

Jeśli nie chcesz lub nie możesz rozwiązać tego tematu po stronie klienta, oto coś, co używa $aspekt (MongoDB>=wymagana wersja 3.4) - nie jest ani szczególnie szybki, ani zbyt ładny, ale może ci pomóc w rozpoczęciu pracy.

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

Jak zawsze w przypadku struktury agregacji, pomocne może być usunięcie poszczególnych etapów z końca potoku i uruchomienie zapytania częściowego w celu zrozumienia, co robi każdy z poszczególnych etapów.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Jak wydrukować minimalny wynik w MongoDB

  2. Jak uzyskać wszystkie klucze kolekcji zawierające pewną wartość (String) w mongodb?

  3. Najlepszy język programowania do implementacji algorytmu DBSCAN odpytującego bazę danych MongoDB?

  4. Agregacja roczna i miesięczna w MongoDB

  5. Mongoose _id zmieniony przed zapisaniem