Is this a good way to check if two users are contacts?

I’m about to set up the functionality for adding contacts, and I need to decide between these three options:
-A
-B
-A+C

A) I’m guessing the most basic way would be to have a Contacts collection, with the same ids as the users, then store an array for everyone that the user is contacts with.
To check, I’d get the array and see if it includes the id.

B) Creating compound indexes (except the order of the two indexes matter, so it I’d have to set it up for both users. also, it requires the memory of the collection + the indexing).

C) Create a collection ContactPairs, with ids having this format “idA_idB” (they are sorted alphabetically before being created/queried), and they can store information like a Date “contactsSince”.

C would be efficient because it uses ids and it would take less space than B. Though it would have to be complemented by A.

What do you think?

Depends what you’re rendering to the client.

[Portrait of Bluray]
You and Bluray share 321 connections. Connect now!
[Connect Now Button]

[Portrait of Doctorpangloss]
You and Doctorpangloss share 10 connections. Connect now!
[Connect Now Button]

[Portrait of MDG]
You and MDG share 188 connections. Connect now!
[Connect Now Button]

Precompute this entire screen and store it as a document.

A relational db approach would be like C. You could have what’s sometimes called a junction table that looks like this:

User_1_ID Connected_User_ID
[id_of_user_1] [id_of_user_2]
[id_of_user_1] [id_of_user_3]
[id_of_user_1] [id_of_user_500]
[id_of_user_1] [id_of_user_750]
[id_of_user_2] [id_of_user_1]
[id_of_user_2] [id_of_user_400]
[id_of_user_2] [id_of_user_438]

…etc.

That way for any user_1, you could easily look up the IDs of all his or her connections, by searching that table for his or her ID.

This works just as well in Mongo as in SQL.

1 Like

I’d probably do something very slightly different,

{
  userIds: [user1Id, user2Id],
  contactsSince: Date
}

If you want to get a list (or count) of all a user’s contacts, you’d do contacts.find({ userIds: userId }). If you want to check if 2 users are contacts, you’d do: contacts.find({userIds: {$all: [userId1, userId2]}}).

You create an index on userIds, mongo then indexes each item in the array. This way when asking for a contact, you don’t need to care about whether they were the “contactee” or the “contacter” - if you care about this, you should store them like this:

{
  contactorId: userId,
  contacteeId: userId,
  contactsSince: Date
}

and create a pair of indexes + a compound index if a single user is likely to have lots of contacts, but to get a list of all a user’s contacts, you’d then have to contacts.find({ $or: [{ contacteeId: userId }, { contactorId: userId }] })

2 Likes

Or you could use one of the exiting packages like the ones in https://atmospherejs.com/socialize