MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

Връзка Mongodb 1 към 1 между поддокументи

Като се има предвид „вдлъбнатината“, която използвам в списъка, това всъщност може да изглежда по-дълго от това, което правите, но всъщност не е.

Това е друг наистина добър пример за използване на $ карта както е достъпно за MongoDB 2.6 и по-нова версия. Все още има известна употреба на $unwind , но масивите, които се „развиват“, всъщност имат само един елемент в тях. Така че, моля, прости ми "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. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Проблем с MapReduce

  2. Mongoose MODEL update() срещу save()

  3. Как да проверите дали вторичният е синхронизиран сега или не

  4. Кога да използваме GridFS на MongoDB?

  5. Уникален индекс не работи с Mongoose / MongoDB