sql >> データベース >  >> NoSQL >> MongoDB

サブドキュメント間のMongodb1to1の関係

    私がリストで使用している「インデント」を考慮すると、これは実際にはあなたがしていることよりも長く見えるかもしれませんが、実際にはそうではありません。

    これは、 $を使用するもう1つの非常に良い例です。マップ MongoDB2.6以降で利用可能です。 $ unwind 、ただし、「巻き戻された」アレイには、実際には1つしかありません。 それらの要素。ですから、私の "Highlander"を許してください。 私が抵抗できなかった参照:)

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

    したがって、最終結果は次のようになります。

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

    「スキーマの変更なし」を要求されたのは知っていますが、 idを保持することをお勧めします。 ここでは一貫したタイプの値です。現在、このプロセスで整数と文字列を混合しています(これが単なる例であることを願っています)。これはお勧めできません。

    したがって、 <を使用して、ここで実際に使用できる「制限付きキャスト」がいくつかあります。強い>$ substr ただし、実際のソリューションは、実際にこれを行う方法が異なる場合があります。本当に修正が必要な場合は、データを修正することを強くお勧めします。

    とにかく、 $のかなりクールな使用法マップ




    1. mongodb、複製とエラー:{$ err:マスターではなくslaveOk =false、コード:13435}

    2. 複数の日付フィールドを使用して日ごとにグループ化

    3. マングースの骨材、someFieldを動的に追加することはできません:{$ not;ヌル }

    4. マングース:ユーザーの完全なリストを取得