Reputation: 124
I'm trying to build (offline first) chat application with react native (and nodeJS, mongoDB, socketIO).
I want to ask what is the best (optimized) way to fetch friends list.
my user model structure:
mongoose.Schema({
phoneNumber: Number,
friends: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
}],
})
as json
[
{
"_id": ObjectId("5e91bcd6cd1630213d95f810"),
"phoneNumber": "+995555555555",
"friends": [
ObjectId("5e57d64d92cc878760086980"),
ObjectId("5e57d64d92cc878760086981")
]
},
...
]
My current approach is I fetch friends list from api and save to localStorage when a user boot the application. So, user can see friends list even if they are offline.
And my concern is if there's 1000 users and they have 200 users in their friend list it would be expensive call.
I can only update localStorage when the user add a friend, but the user won't be able to see if a friend change their avatar or username, etc..
So, what is the best way to keep up-to-date friend list?
Upvotes: 0
Views: 585
Reputation: 300
Maybe you could change your structure to have a Connections collection which stores a pair of userIds. I can't say this would be more optimal but it does leave you more room for expansion, for example this would support having connection types, some connections might be friends, others could be from message chains between people who are not friends, not sure what you'd call this exactly but think of something like message requests in Facebook messenger as an example.
Another advantage of this is it stops you creating an accidental megadoc as someone's friend list gets bigger and bigger. It also means that when you fetch a friend user doc you won't also be fetching that friends friends, perhaps this is where the optimisation you're looking for is.
Connections could look something like this:
{
instigator: ObjectId("5e91bcd6cd1630213d95f810"),
subordinate: ObjectId("5e57d64d92cc878760086980"),
type: 'friendship'
}
{
instigator: ObjectId("5e91bcd6cd1630213d95f810"),
subordinate: ObjectId("5e57d64d92cc878760086981"),
type: 'friendship'
}
to represent the two friendships in your example.
To get the friends of one user you would query something like Connections.find({ users: ObjectId('5e91bcd6cd1630213d95f810'), type: 'friendship' })
You could use an aggregate or mongoose populate to swap the userIds out for their docs before returning them to the client.
Upvotes: 2