Imagine a bacon-wrapped Ferrari. Still not better than our free technical reports.
See all our reports

Why you should use XRebel if you are using MongoDB

MongoDB is the most popular NoSQL data store available today. MongoDB organizes JSON-like documents into collections. One collection may contain multiple documents with different structures. It is then up to the user to organize these documents by logically grouping ‘em into collections.

The data model design is superbly covered in the MongoDB documentation:


In this blog post I’d like to evaluate how XRebel helps detect MongoDB query invocations in Java web applications. A developer can detect “N+1 select” problems with XRebel, and then redesign the data model for optimal use.

Let us consider a simple example – a data model of a trivial blog post engine. A collection of articles, each having a collection of comments associated with them.

To acquire all articles with the associated comments, one must first run a query into the articles collection. And then run a query to fetch the corresponding comments for each article:

MongoClient mongoClient;
DB db;
....
private void getArticlesWithComments() {
   List<Article> articles = getArticles();
   for (Article article : articles) 
       getComments(article.getId());
}

private List<Article> getArticles() {
   DBCollection articles = db.getCollection("articles");
   List<Article> result = new ArrayList<>();
   try (DBCursor articlesCursor = articles.find()) {
       while (articlesCursor.hasNext()) 
           result.add(Article.from(articlesCursor.next()));
   }
   return result;
}

private List<Comment> getComments(Object articleId) {
   DBCollection comments = db.getCollection("comments");
   BasicDBObject query = new BasicDBObject("article_id",
           new BasicDBObject("$eq", String.valueOf(articleId)));
   List<Comment> result = new ArrayList<>();
   try (DBCursor commentsCursor = comments.find(query)) {
       while (commentsCursor.hasNext())
           result.add(Comment.from(commentsCursor.next()));
   }
   return result;
}

This is a very typical example that essentially reveals the N+1 select problem. Unfortunately, MongoDB doesn’t provide join semantics to fetch all this data with a single query. And even when using database references the database driver would not resolve a DBRef into a JSON document. Read more.

XRebel

Considering the example of a simple blog model, XRebel would display the following information when a list of articles is retrieved along with the corresponding comments.

From within the XRebel UI you can easily detect, that there is the “N+1 select” problem in the code.

It is possible to reduce the number of queries by delegating the query execution to the database server with the mapReduce function. This would reduce the number of network calls, but the drawback is that mapReduce would run in a single thread. Obviously, this doesn’t scale well.

Another option is to restructure the data model: to embed the comments in our example right into the articles. However, in a real life application, it depends on how the data is accessed. If the comments would be accessed individually then it wouldn’t make much sense to embed them into articles. The 6 rules of thumb for MongoDB schema design is a good place to start for designing the data model depending on your particular use case.

In practice, however, developers tend to implement N+1 selects logic in the application code. XRebel gives you the insight required to detect this situation early and to reconsider your design decisions before the code goes live.


TRY XREBEL FREE