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

Projektuj, aby filtrować właściwość w drugiej zagnieżdżonej tablicy

Ponieważ Twoim wymaganiem jest po prostu „zaprojektowanie” dokumentu tak, aby pole było zamaskowane, tak, struktura agregacji jest narzędziem do tego. Trochę zajmuje jednak ogarnięcie całego procesu podczas rozwijania tablic i rekonstrukcji.

Więc to, czego chciałeś, to:

db.collection.aggregate([
    { "$unwind": "$questions" },
    { "$unwind": "$questions.answers" },
    { "$group": { 
        "_id": {
            "_id": "$_id",
            "name": "$name",
            "description": "$description",
            "qid": "$questions._id",
            "question": "$questions.question"
        },
        "answers": {
            "$push": {
                "_id": "$questions.answers._id",
                "answer": "$questions.answers.answer"
            }
        }
    }},
    { "$project": {
        "questions": {
            "_id": "$_id.qid",
            "question": "$_id.question",
            "answers": "$answers"
        }
    }},
    { "$sort": { "_id": 1, "questions._id": 1 } },
    { "$group": {
        "_id": "$_id._id",
        "name": { "$first": "$_id.name" },
        "description": { "$first": "$_id.description" },
        "questions": { "$push": "$questions" }
    }}
])

Ale tak naprawdę, jeśli masz MongoDB 2.6 lub nowszą wersję, nie musisz $rozwiń i $group wyniki z powrotem razem, aby pominąć to pole. Możesz teraz to zrobić za pomocą $project i $map operator, który działa z tablicami:

db.collection.aggregate([
    { "$project": {
        "name": 1,
        "description": 1,
        "questions": {
            "$map": {
                "input": "$questions",
                "as": "q",
                "in": {
                    "$ifNull": [
                        { 
                            "_id": "$$q._id",
                            "question": "$$q.question",
                            "answers": {
                                "$map": {
                                    "input": "$$q.answers",
                                    "as": "el",
                                    "in": {
                                        "$ifNull": [
                                            { "_id": "$$el._id", "answer": "$$el.answer" },
                                            false
                                        ]
                                    }
                                }
                            }
                        },
                        false
                    ]
                }
            }
        }
    }}
])

Przepraszamy za wcięcie, które trochę przesuwa się poza stronę, ale nadal jest łatwiejszy do odczytania w porównaniu.

Pierwszy $map przetwarza tablicę pytań na miejscu i przekazuje do wewnętrznego $mapa który zwraca wewnętrzne dokumenty tablicy odpowiedzi bez pola „isCorrectAnswer”. Używa własnych zmiennych do reprezentowania elementów, a użycie $ifNull tam jest tylko dlatego, że część "in" $mapa operator oczekuje oceny warunku na każdym z tych elementów.

Ogólnie trochę szybciej, ponieważ nie musisz przechodzić przez $odpręż i $group operacje tylko w celu usunięcia pola. Tak więc naprawdę staje się to tylko „projekcją”, której można się spodziewać.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Skrypt powłoki MongoDB wykorzystujący projekcję do formatowania daty i uzyskiwania czasu lokalnego

  2. MongoDB bulkWrite()

  3. Uwierzytelnianie użytkownika w kolbie

  4. Czy można skonfigurować częstotliwość pulsu lub limit czasu dla repliki?

  5. Wybierz dokumenty, w których wszystkie wartości w polu tablicy istnieją w innej tablicy