Hi,
so there are two collections: posts and likes
the goal is to handle a post like action (can done in three separated processes):
- make sure the post exists
- if (1) is a success; insert into likes (inserted data is post id and user id; both are indexed (compound index))
- if (2) is a success; update the post likes field: increase by 1
it’s pretty simple to do that:
database.PostsCollection.FindOne(database.Ctx, filter)
database.LikesCollection.InsertOne(database.Ctx, like)
database.PostsCollection.UpdateOne(database.Ctx, filter, update)
where:
filter := bson.M{"_id": postID}
like is a like object
update := bson.D{{"$inc", bson.D{{"likes", 1}}}}
The challenge now is to reduce the number of queries. (or the performances overall)
i found FindOneAndUpdate()
but this requires process 1 and 3 to be adjacent
i found a way to benefit from this but i don’t really like it, the solution is as follow:
- insert into likes
- if (1) is a success; find the post and update it’s likes field: increase by 1
- if (2) is a failure; delete what we inserted into likes
the only reason i think this is faster because in most cases we will only perform two queries (assuming that the users are innocent and won’t try to flood the system XD) while in the first solution we will always perform three queries (again assuming that all the users are innocent)
the reason why i don’t like this, because of the fact that we are submitting unreal data that may be fake and it have to be deleted later, this fake data can be retrieved by users in case of another query came just before the fake data is deleted…
ps: i think there is an option to make the update statement based on a condition but i don’t know if this condition can relay on other collections, or even in the results of other collections insertion
so any ideas?
any help is appreciated