Question

I have a quite common use case - a list of comments. Each comment has an author.

I'm storing the reference from a comment to the author using a reference, since an author can make multiple comments.

Now I'm working with ReactiveMongo and want to try to keep the database access asynchronous, but in this case, I don't know how. I do an asynchronous access to the database, to get the comments, but then for each comment I have to get the author, and until now the only way I know is to loop through the comments and get the user synchronously:

val userOption:Option[JsObject] = Await.result(usersCollection.find(Json.obj("id" -> userId).one[JsObject], timeout)
//...

Other than that, I could:

  • Get each user asynchronously but then I have to introduce some functionality to wait until all user were fetched, in order to return the response, and my code is likely to become a mess.

  • Store the complete user object - at least what I need for the comment (picture, name and such) in each comment. This redundancy could become troublesome to manage, since each time a user changes something (relevant to the data stored in the comments) I would have to go through all the comments in the database and modify it.

What is the correct pattern to apply here?

Was it helpful?

Solution

I tackled this exact problem a while ago.

There are no joins in mongo. You have to manually take care of the join.

Your options are:

  1. Loop through each comment entry and query mongo for the user. this is what you're doing.
  2. Get all user id's from comments, query mongo for the users matching these ids, then take care to match user to comment.This is just what you did but a little more optimized.
  3. Embed the user in comments or comments in users. Wouldn't recommend this, this is probably not the right place for comments/users.
  4. Think of what set of data do you need from user when displaying a comment, and embed just this info in comment

I ended up going with the last option.
We embedded the user id, first and last name in each comment. This info is unlikely to change (possibly not even allowed to change after creation?).
If it can change then it is not too hard to tailor the update-user method to update the related comments with the new info (we did that too).
So now no join is needed.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top