Help reducing number of queries

so there are two collections: posts and likes
the goal is to handle a post like action (can done in three separated processes):

  1. make sure the post exists
  2. if (1) is a success; insert into likes (inserted data is post id and user id; both are indexed (compound index))
  3. 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)

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:

  1. insert into likes
  2. if (1) is a success; find the post and update it’s likes field: increase by 1
  3. 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

Hello : )

FindOneAndUpdate can be used for post collection.
And if succefull you can insert to the likes collection.

We can do this inside a transaction,that we can abort also if something goes wrong.
Abort transactions

oh i missed that, this will sure help
now it’s down to 2 queries
(start transaction)

  1. insert into likes
  2. find the post and update it’s likes filed: increase by 1
    (end transaction)

using a transaction seems the right way to go
but it seems to effect the performance a little
how can this be tuned using read/write concern ?