2

I’m trying to decide which of the following schemas is most efficient for implementation with mongodb. I require to keep track of friend id’s & mutual friend counts for each user in a system (user_id is unique across the collection). The number of friends may be up to 100,000.

Schema 1

{
“_id” : “…”,
“user_id” : “1”,
friends : {
    “2” : {
        “id” : “2”,
        “mutuals” : 3
    }
     “3” : {
         “id” : “3”,
         “mutuals”: “1”
    }

   “4” : {
         “id” : “4”,
         “mutuals”: “5”
    }
}

}

Schema 2

{
“_id” : “…”,
“user_id” : “1”,
friends : [
   {
        “id” : “2”,
        “mutuals” : 3
    },
    {
         “id” : “3”,
         “mutuals”: 1
    },
   {
         “id” : “4”,
         “mutuals”: 5
    }
]

}

Requirements:

  1. Given a user_id and friend id update the document such that if friend id exists increment mutuals by 1, else add new friend with a mutuals of 1
  2. Given a user_id and friend id update the document such that if friend exists and mutual count > 1 then decrement mutual count by 1, else remove friend from document
  3. With a list of ids, lookup in the document to identify which friend ids exist (I know this is something that can be done client side, but am interested in server side solution)
  4. What indexes should be used to speed up the above?

In my work in progress I have implemented much of this with schema 1, but am now starting to realise it may not be as suitable as schema 2. However, I am having trouble finding the most efficient methods for the above questions.

1
  • I stumbled upon this post thanks to Google - top result. I'll just leave this here for anyone else searching in the future: docs.mongodb.org/manual/core/update/… Commented May 21, 2013 at 9:53

1 Answer 1

1

AFAIK, points 1 & 2 cannot be done in a single statement in mongoDB. You would probably have to query mongodb to check if the particular user_id, friend.id combination exists. If it does then update else add to friend array. Refer to JavaSscript code below:

    use <dbname>;
    var FriendsList;
    var FriendId = "9";
    var UserId = "1";
    var Friends = db.Friends.findOne({"user_id":UserId, "friends.id":FriendId});
    if (Friends != null){ 
        print ("Friends is not null");
        FriendsList = Friends.friends;
        // print (FriendsList.toSource());
        for (var i = 0; i < FriendsList.length; i++){
            var curFriend = FriendsList[i];
            if (curFriend["id"] == FriendId){
                    curFriend["mutuals"] = curFriend["mutuals"] + 1;
                    FriendsList[i] = curFriend;
                    break;
                }
        }
    }
    if (Friends == null){
            print ("Friends is null");
            Friends = db.Friends.findOne({"user_id":UserId});
            FriendsList = Friends.friends;
            FriendsList.push({"id":FriendId, "mutuals":1});
            // print (FriendsList.toSource());
    }
        Friends.friends = FriendsList;
        db.Friends.save(Friends);

Pls share if you find a better way to do this.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for that, do you have any information in regard to comparison of schemas for requirement 3?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.