For users, I think your current schema is fine. Keeping multiple addresses, phone numbers, and email addresses in arrays is good because there shouldn't be too many of them for a particular person and it's easy to query for "who has this email address" or "give me all the phone numbers of this person". You do seem to have a redundant e-mail
field though - is that a special email, like the address for the account, that's distinguished from a contact email? If so I'd give it a descriptive name for the sake of other maintainers, a name like account_email
. I wouldn't keep the photo as a blob, but you said that is some other requirement so I won't critique it.
I like the idea of doing contacts with groups using a separate contacts collection. I'd have a contacts
collection with each document representing one contact
{
"_id" : ObjectId("..."),
"owner_id" : ObjectId("..."), // reference to user document of contact owner
"contact_id" : ObjectId("..."), // reference to user document of contact
"group" : "Rivals" // group name
}
Index on { "owner_id" : 1, "contact_id" : 1 }
and maybe { "owner_id" : 1, "group" : 1 }
and then queries like the following will be quick:
// get all contacts for user x
db.contacts.find({ "owner_id" : x })
// is user y a contact of user x?
db.contacts.count({ "owner_id" : x, "contact_id" : y }) != 0
// get all contacts in group "family" for user x
db.contacts.find({ "owner_id" : x, "group" : "family" })
Once you retrieve contacts, in order to retrieve human-friendly display information you will need to do a second query (application-level join) to retrieve the actual user documents of the contacts. If you want, you can denormalize some of the contact info into the contact document
{
"_id" : ObjectId("..."),
"owner_id" : ObjectId("..."), // reference to user document of contact owner
"contact_id" : ObjectId("..."), // reference to user document of contact
"group" : "Rivals", // group name
"contact_name" : "Franke Frankers"
}
You won't need to do a second query if you include commonly needed info, but if the contact updates his/her information you may need to update every contact document referencing them.