sql >> Database teknologi >  >> NoSQL >> MongoDB

Mongodb 1to1 relation mellem underdokumenter

I betragtning af den "indrykning", jeg bruger i listen, kan dette faktisk se længere ud end det, du gør, men det er det faktisk ikke.

Dette er endnu et rigtig godt eksempel på brug af $ kort som tilgængelig for MongoDB 2.6 og nyere. Der er stadig en vis brug af $unwind , men de arrays, der "afvikles", har faktisk kun én element i dem. Så tilgiv venligst min "Highlander" referencer som jeg ikke kunne modstå :)

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" }
    }}

])

Så slutresultatet ville være:

{
    "_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"
            }
    ]
}

Jeg ved, at du bad om "ingen skemaændringer", men egentlig ikke en skemaændring for at sige, at det er en god idé at beholde dit id værdier her af ensartet type. I øjeblikket blander du heltal og strenge i denne proces (håber det kun er et eksempel), hvilket ikke er en god idé.

Der er således nogle "begrænsede casting", der faktisk er tilgængelige her ved hjælp af strong>$substr , men din faktiske løsning kan variere i, hvordan du virkelig gør dette. Jeg anbefaler på det kraftigste at rette dataene, hvis de virkelig trænger til at blive rettet.

I hvert fald en ret cool brug for $ kort




  1. pymongo auth mislykkedes i python-script

  2. Java MongoDB:Hvad er forskellen mellem com.mongodb.DB og com.mongodb.client

  3. Forskellen mellem majoritet og lineariserbar

  4. Kan ikke oprette forbindelse til en Mongodb-pod i Kubernetes (Forbindelse nægtet)