Add how many times a shortcut has been favorited
Closed this issue · 6 comments
Right now a user has a reference to all the shortcuts they've favorited. This makes it so that shortcuts have no reference to how many times they've been favorited. We want to have both, and have some way to keep them in sync.
Here's a couple ways to accomplish this that I looked into:
1. Maintain a favorited_count field on the shortcut document
With this approach, whenever someone favorites a shortcut the application would increment the field. Here's a pseudocode example of the write:
function favorite_shortcut(user_id, shortcut_id) {
db.users.update({_id: user_id}, {$push: {favorites: shortcut_id}});
db.shortcuts.update({_id, shortcut_id}, {$inc: {favorites_count: 1}})
}
Pros:
- Reads are really easy
- Reads are really fast
Cons:
- It's important that the two documents (
users
andshortcuts
) stay in sync. Since MongoDB doesn't provide a way to do multi-document atomic updates, the application has to. Here's the two-phase commit docs we'd need to follow. This is pretty notoriously unreliable in distributed MongoDB deployments, but is probably fine for ShortcutJunkie.
2. Create an index on the favorites field
Is we create an index on the favorites field, then MongoDB should maintain the relationship for us. For example, if the user collection looks like this:
{
_id: 1,
favorites: [1, 2]
},
{
_id: 2,
favorites: [2, 3]
}
Then the users.favorites index will look like this (conceptually, I don't know how they actually store it)
{
value: 1,
referenced_by: [1]
},
{
value: 2,
referenced_by: [1, 2]
},
{
value: 3,
referenced_by: [2]
}
Pros:
- Querying for users who have favorited a shortcut should be pretty fast. When we query for all users who have favorited the shortcut with _id: 2, MongoDB looks at a single index and grabs the referenced users instead of scanning the entire users collection.
- We can reuse this solution if we want to show a list of users who have favorited a shortcut, instead of just a count.
- No two-phase commit to write.
Cons:
- Probably not as fast on retrieval as maintaining a count on the shortcut collection.
- Since all indexes need to fit in RAM, this could be an operational annoyance later on if the data grows significantly.
If you want to add the ability to see the users who have favorite a shortcut then I'd lean towards the index approach.
I think having the number of times that a shortcut has been favorited would probably get us everything we need. I can only think of seeing the users who have favorite a shortcut so that you can see other shortcuts they've favorited, which doesn't seems like a super valuable use case.
Can you think of any other situations where we could use seeing the users? Otherwise I'd lean towards just having a count and keeping them in sync.
Thanks, this is awesome!
Also, let me know if you want to copy the data from production into your local machine, I can email you the commands for doing that.
Yes, I would love some data to insert!
I sent you an email with the command to the email on your website. Hope that helps!