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

Relacja Mongodb 1to1 między poddokumentami

Biorąc pod uwagę „wcięcie”, którego używam we wpisie, może to w rzeczywistości wyglądać dłużej niż to, co robisz, ale tak naprawdę nie jest.

To kolejny naprawdę dobry przykład użycia $ mapa jako dostępny dla MongoDB 2.6 i nowszych. Nadal istnieje pewne zastosowanie $unwind , ale tablice „odwijane” w rzeczywistości mają tylko jeden element w nich. Więc proszę wybacz mojemu "Góralowi" referencje, którym nie mogłem się oprzeć :)

db.users.aggregate([

    // Match your document or documents
    { "$match": {
        "commentUpvotes.id": 12
    }},

    // Get the one "up-votes" entry that matches
    { "$project": {
        "posts": 1,
        "comments": 1,
        "commentUpVotes": {
            "$setDifference": [
                { 
                    "$map": {
                        "input": "$commentUpvotes",
                        "as": "el",
                        "in": {
                            "$cond": [
                                { "$eq": [ "$$el.id", 12 ] },
                                "$$el",
                                false
                            ]
                        }  
                    }
                },
                [false]
            ]
        }
    }},

    // There is only one!
    { "$unwind": "$commentUpVotes" },

    // Get the one comments entry that matches
    { "$project": {
        "posts": 1,
        "comments": {
            "$setDifference": [
                { 
                    "$map": {
                        "input": "$comments",
                        "as": "el",
                        "in": {
                            "$cond": [
                                { 
                                    "$eq": [ 
                                        { "$substr": [ "$$el.id", 0, 4 ] }, 
                                        "$commentUpVotes.commentId"
                                    ] 
                                },
                                "$$el",
                                false
                            ]
                        }  
                    }
                },
                [false]
            ]
        },
        "commentUpVotes": 1
    }},

    // And there is only one!
    { "$unwind": "$comments" },

    // Get the one post that matches
    { "$project": { 
        "posts": {
            "$setDifference": [
                { 
                    "$map": {
                        "input": "$posts",
                        "as": "el",
                        "in": {
                            "$cond": [
                                { 
                                    "$eq": [ 
                                        "$$el.id", 
                                        "$comments.postId"
                                    ] 
                                },
                                "$$el",
                                false
                            ]
                        }  
                    }
                },
                [false]
            ]
        },
        "comments": 1,
        "commentUpVotes": 1
    }},

    // Optionally group back to arrays. There can be only one!
    { "$group": {
        "_id": "$_id",
        "posts": { "$first": "$posts" },
        "comments": { "$push": "$comments" },
        "commentUpVotes": { "$push": "$commentUpVotes" }
    }}

])

Wynik końcowy byłby więc następujący:

{
    "_id" : ObjectId("539065d3cd0f2aac5f55778e"),
    "posts" : [
            {
                    "title" : "post1",
                    "id" : "123"
            }
    ],
    "comments" : [
            {
                    "id" : 1910,
                    "postId" : "123",
                    "title" : "comment1",
                    "comment" : "some comment",
                    "user" : "user13"
            }
    ],
    "commentUpVotes" : [
            {
                    "id" : 12,
                    "commentId" : "1910",
                    "upvotedBy" : "user91"
            }
    ]
}

Wiem, że prosiłeś o „brak zmian w schemacie”, ale tak naprawdę nie o zmianę schematu, aby powiedzieć, że dobrym pomysłem jest zachowanie id wartości tutaj spójnego typu. Obecnie mieszasz w tym procesie liczby całkowite i łańcuchy (mam nadzieję, że to tylko przykład), co nie jest dobrym pomysłem.

W związku z tym istnieje pewne "ograniczone przesyłanie", które faktycznie jest dostępne tutaj przy użyciu $substr , jednak rzeczywiste rozwiązanie może się różnić w zależności od tego, jak to zrobić. Zdecydowanie sugeruję naprawienie danych, jeśli naprawdę wymagają naprawy.

W każdym razie całkiem fajne użycie dla $ mapa




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Błąd indeksu tekstu MongoDB:zmiana języka nie jest obsługiwana

  2. Spring Boot i jak skonfigurować szczegóły połączenia z MongoDB?

  3. Jak wykonać zapytanie tablicowe identyfikatorów w Mongoose?

  4. Jak zatrzymać wstawianie zduplikowanych dokumentów do kolekcji mongodb

  5. Zatapianie danych tematycznych od producenta Javy do Mongodb